Working with forms and Vuetify
Vuetify is a great component library, but it doesn't really guide you through the Javascript or Typescript part. I usually use Typescript and found a good way to handle forms throughout all components. It all start's with an interface:
export interface FormDefinition {
valid: boolean;
fields: {
[key: string]: any;
};
rules?: {
[key: string]: any;
};
}
With every component I'm creating, I will extend the FormDefinition
with a custom Form
interface:
interface Form extends FormDefinition {
fields: {
firstName: string;
...
},
rules: {
firstName: ((message?: string) => {})[];
...
}
}
The rules are functions which I put into a form-rules.ts
and import when needed. For example this is a rule to check if a form field is required:
export function requiredRule(message = 'Dieses Feld muss gefüllt sein'): (value: any) => boolean|string {
return (value) => (!!value || value === 0) || message;
}
This way I only have write those rules once and can use them everywhere. A full implementation of the form in a component would look like this:
@Component
export default class CreateEditUserDialogComponent {
form: Form = {
valid: false,
fields: {
email: '',
firstName: '',
lastName: ''
},
rules: {
email: [
requiredRule(),
emailRule()
],
firstName: [
requiredRule()
],
lastName: [
requiredRule()
]
}
};
...
}
Within the template I will have highlighting and error spotting by the IDE:
<v-form ref="form" v-model="form.valid" @submit.prevent="onSubmit">
<v-card-text>
<v-row>
<v-col cols="12" sm="6">
<v-text-field v-model="form.fields.firstName" label="First name" :rules="form.rules.firstName" />
</v-col>
<v-col cols="12" sm="6">
<v-text-field v-model="form.fields.lastName" label="Last name" :rules="form.rules.lastName" />
</v-col>
</v-row>
<v-row>
<v-col cols="12" sm="6">
<v-text-field type="email" v-model="form.fields.email" label="Email" :rules="form.rules.email" />
</v-col>
</v-row>
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn text @click="hide()">
Cancel
</v-btn>
<v-btn type="submit" color="primary" :disabled="!form.valid">
Save
</v-btn>
</v-card-actions>
</v-form>
All rules are connected to the form and with the form.valid
I can disable the submit button without having to use any kind of form state validation methods.
I hope this will help you with your Vuetify forms. Let me know if there is something that can be improved.