Vue.js doesn’t come with any form validation capabilities by default.
Therefore, we need to add our own form validation library or with our own code.
In this article, we’ll look at how to validate forms with Vuelidate.
$error vs $anyError
We can get form validation errors with the $error
and $anyError
validation property.
$dirty
and $anyDirty
checks if the forms have been modified.
For example, we can write:
<template>
<div id="app">
<div>
<div :class="{ 'form-group--error': $v.name.$error }">
<label>name</label>
<input v-model.trim="$v.name.$model">
<div class="error" v-if="!$v.name.required">name is required.</div>
</div>
<div :class="{ 'form-group--error': $v.age.$error }">
<label>age</label>
<input v-model.trim="$v.age.$model">
</div>
<div class="error" v-if="!$v.age.required">age is required.</div>
</div>
</div>
</template>
<script>
import { required } from "vuelidate/lib/validators";
export default {
name: "App",
data() {
return {
name: "",
age: ""
};
},
validations: {
name: {
required
},
age: {
required
}
}
};
</script>
Then we gave the $v.age.$error
and $v.name.$error
properties to get the errors.
If they’re true
, then the form-group--error
class will be applied.
Validation Groups
We can create validation groups to validate all the form fields together.
For example, we can write:
<template>
<div id="app">
<div>
<div :class="{ 'form-group--error': $v.name.$error }">
<label>name</label>
<input v-model.trim="$v.name.$model">
<div class="error" v-if="!$v.name.required">name is required.</div>
</div>
<div :class="{ 'form-group--error': $v.age.$error }">
<label>age</label>
<input v-model.trim="$v.age.$model">
<div class="error" v-if="!$v.age.required">age is required.</div>
</div>
<div :class="{ 'form-group--error': $v.phone.mobile.$error }">
<label>mobile phone</label>
<input v-model.trim="$v.phone.mobile.$model">
<div class="error" v-if="!$v.phone.mobile.required">mobile phone is required.</div>
</div>
<div v-if="$v.validationGroup.$error">group is invalid.</div>
</div>
</div>
</template>
<script>
import { required } from "vuelidate/lib/validators";
export default {
name: "App",
data() {
return {
name: "",
age: "",
phone: {
mobile: ""
}
};
},
validations: {
name: {
required
},
age: {
required
},
phone: {
mobile: {
required
}
},
validationGroup: ["name", "age", "phone.mobile"]
}
};
</script>
We added the validationGroup
property in the validations
property to add a validation group.
It has an array of strings with the property names.
If the property is nested, then the property is separated by a dot.
Then in the template, we get the $v.validationGroup.$error
property to see if there’re any errors in the fields in the group.
Collections Validation
We can validate collections with the $each
keyword.
For instance, we can write:
<template>
<div id="app">
<div v-for="(v, index) in $v.people.$each.$iter">
<div class="form-group" :class="{ 'form-group--error': v.$error }">
<label>Name</label>
<input v-model.trim="v.name.$model">
</div>
<div v-if="!v.name.required">Name is required.</div>
<div
v-if="!v.name.minLength"
>Name must have at least {{ v.name.$params.minLength.min }} letters.</div>
</div>
<div>
<button class="button" [@click](http://twitter.com/click "Twitter profile for @click")="people.push({name: ''})">Add</button>
<button class="button" [@click](http://twitter.com/click "Twitter profile for @click")="people.pop()">Remove</button>
</div>
<div class="form-group" :class="{ 'form-group--error': $v.people.$error }"></div>
<div
v-if="!$v.people.minLength"
>List must have at least {{ $v.people.$params.minLength.min }} elements.</div>
<div v-else-if="!$v.people.required">List must not be empty.</div>
<div v-else-if="$v.people.$error">List is invalid.</div>
<button class="button" [@click](http://twitter.com/click "Twitter profile for @click")="$v.people.$touch">$touch</button>
<button class="button" [@click](http://twitter.com/click "Twitter profile for @click")="$v.people.$reset">$reset</button>
</div>
</template>
<script>
import { required, minLength } from "vuelidate/lib/validators";
export default {
name: "App",
data() {
return {
people: [
{
name: "mary"
},
{
name: ""
}
]
};
},
validations: {
people: {
required,
minLength: minLength(3),
$each: {
name: {
required,
minLength: minLength(2)
}
}
}
}
};
</script>
In the validations
property, we have the $each
property with the minLength
property to set the min length of the people
array.
Also, we have the minLength
property in the name
field to check if the name entered has the required length.
In the template, we have the $touch
and $reset
methods that we can use to trigger validation and reset the validation state respectively.
Conclusion
We can validate lists and check for errors with Vuelidate.