Form validation is an important part of any app.
In this article, we’ll look at how to use Vee-Validate 4 in our Vue 3 app for form validation.
Validation Behavior
Vee-Validate runs validate when the change
event is emitted or when the value is changed externally.
Customizing Validation Triggers
We can change when fields are validated.
To do this, we use the configure
function to change this behavior:
<template>
<Form @submit="submit" :validation-schema="schema" v-slot="{ errors }">
<Field name="email" as="input" />
<span>{{ errors.email }}</span>
<br />
<Field name="password" as="input" type="password" />
<span>{{ errors.password }}</span>
<br />
<button>Submit</button>
</Form>
</template>
<script>
import { configure, Field, Form } from "vee-validate"; `
import * as yup from "yup";
configure({
validateOnBlur: true,
validateOnChange: true,
validateOnInput: false,
validateOnModelUpdate: true,
});
export default {
components: {
Field,
Form,
},
data() {
const schema = yup.object().shape({
email: yup.string().required().email(),
password: yup.string().required().min(8),
});
return {
schema,
};
},
methods: {
submit() {},
},
};
</script>
validateOnBlur
means validation will run when the blur
event is emitted.
validateOnChange
means validation will run when the change
event is emitted.
validateOnInput
means validation runs when the input
event is emitted.
And validateInModelUpdate
means validation runs when the model reactive properties updates.
Displaying Error Messages
We can create our own field and display the error messages by using the slot props.
For instance, we can write:
<template>
<Form @submit="submit" :validation-schema="schema">
<Field :rules="rules" v-slot="{ field, errors, errorMessage }" name="email">
<input v-bind="field" type="text" />
<p>{{ errors[0] }}</p>
<p>{{ errorMessage }}</p>
</Field>
<br />
<button>Submit</button>
</Form>
</template>
<script>
import { Field, Form } from "vee-validate";
import * as yup from "yup";
export default {
components: {
Form,
Field,
},
data() {
const schema = yup.object().shape({
email: yup.string().required().email(),
});
return {
schema,
};
},
methods: {
submit() {},
},
};
</script>
We have the validation-schema
prop with the validation schema.
And in the Field
component, we have the input
element.
We pass in the field
properties as props to make the validation trigger on the input.
And we show the errors with the errors[0]
or errorMessage
expressions.
Also, we can display all the error messages for the fields by iterating over the errors
object:
<template>
<Form v-slot="{ errors }" :validation-schema="schema">
<template v-if="Object.keys(errors).length">
<p>Please correct the following errors</p>
<ul>
<li v-for="(message, field) in errors" :key="field">
{{ message }}
</li>
</ul>
</template>
<Field name="name" as="input" :rules="rules" />
<Field name="email" as="input" :rules="rules" />
<Field name="password" as="input" :rules="rules" />
</Form>
</template>
<script>
import { Field, Form } from "vee-validate";
import * as yup from "yup";
export default {
components: {
Field,
Form,
},
data() {
const schema = yup.object().shape({
email: yup.string().required().email(),
password: yup.string().required().min(8),
name: yup.string().required(),
});
return {
schema,
};
},
methods: {
submit() {},
},
};
</script>
We get the keys from the errors
object and loop through them with the v-for
directive.
The message
is the value, and we display them in the li
.
Conclusion
We can change when validation is run and display error messages our way in our Vue 3 app with Vee-Validate 4.