Vue.js validation
Forms
Want more?
Visit: Vee-Validate
Vuelidate is a simple, lightweight, model-based validation library for Vue applications. Validation rules are added to a validation object where a given component is defined (instead of directly inside the DOM).
What is Vuelidate?
import { required, minLength, between }
from 'vuelidate/lib/validators'
export default {
data() { return {
name: '', age: 0 }
},
validations: {
name: {
required,
minLength: minLength(4)
},
age: {
between: between(20, 30)
}
}
}
<div>
<div :class="{ 'form-group--error': $v.name.$error }">
<label >Name</label>
<input v-model.trim="$v.name.$model"/>
</div>
<div class="error" v-if="!$v.name.required">Field is required</div>
<div class="error" v-if="!$v.name.minLength">
Name must have at least {{$v.name.$params.minLength.min}} letters.</div>
<div :class="{ 'form-group--error': $v.age.$error }">
<label >Age</label>
<input v-model.trim.lazy="$v.age.$model"/>
</div>
<div class="error" v-if="!$v.age.between">
Must be between {{$v.age.$params.between.min}} and {{$v.age.$params.between.max}}</div>
</div>
$v: {
name: {
"required": false,
"minLength": false,
"$invalid": true,
"$dirty": false,
"$error": false,
"$pending": false
},
age: {
"between": false
"$invalid": true,
"$dirty": false,
"$error": false,
"$pending": false
}
}
Provided validators
import { required, minLength } from 'vuelidate/lib/validators'
export default {
data() {
return {
name: '',
age: 0,
submitStatus: null
}
},
validations: {
name: {
required,
minLength: minLength(4)
}
},
methods: {
submit() {
console.log('submit!')
this.$v.$touch()
if (this.$v.$invalid) {
this.submitStatus = 'ERROR'
} else {
// do your submit logic here
this.submitStatus = 'PENDING'
setTimeout(() => {
this.submitStatus = 'OK'
}, 500)
}
}
}
}
Forms JS
<form @submit.prevent="submit">
<div class="form-group" :class="{ 'form-group--error': $v.name.$error }">
<label class="form__label">Name</label>
<input class="form__input" v-model.trim="$v.name.$model"/>
</div>
<div class="error" v-if="!$v.name.required">Name is required</div>
<div class="error" v-if="!$v.name.minLength">
Name must have at least {{$v.name.$params.minLength.min}} letters.</div>
<button class="button" type="submit" :disabled="submitStatus === 'PENDING'">
Submit!</button>
<p class="typo__p" v-if="submitStatus === 'OK'">
Thanks for your submission!</p>
<p class="typo__p" v-if="submitStatus === 'ERROR'">
Please fill the form correctly.</p>
<p class="typo__p" v-if="submitStatus === 'PENDING'">
Sending...</p>
</form>
Forms HTML
import { required } from 'vuelidate/lib/validators'
export default {
data() {
return {
flatA: '',
flatB: '',
forGroup: {
nested: ''
}
}
},
validations: {
flatA: { required },
flatB: { required },
forGroup: {
nested: { required }
},
validationGroup: ['flatA', 'flatB', 'forGroup.nested']
}
}
Validation Groups
If you want to create a validator that groups many otherwise unrelated fields together, you can create a validation group.
<div>
<div class="form-group" :class="{ 'form-group--error': $v.flatA.$error }">
<label class="form__label">Flat A</label>
<input class="form__input" v-model.trim="$v.flatA.$model"/>
</div>
<div class="error" v-if="!$v.flatA.required">Field is required.</div>
<div class="form-group" :class="{ 'form-group--error': $v.flatB.$error }">
<label class="form__label">Flat B</label>
<input class="form__input" v-model.trim="$v.flatB.$model"/>
</div>
<div class="error" v-if="!$v.flatB.required">Field is required.</div>
<div class="form-group" :class="{ 'form-group--error': $v.forGroup.nested.$error }">
<label class="form__label">Nested field</label>
<input class="form__input" v-model.trim="$v.forGroup.nested.$model"/>
</div>
<div class="error" v-if="!$v.forGroup.nested.required">Field is required.</div>
<div class="form-group" :class="{ 'form-group--error': $v.validationGroup.$error }"></div>
<div class="error" v-if="$v.validationGroup.$error">Group is invalid.</div>
</div>
Validation Groups
import { required, minLength } from 'vuelidate/lib/validators'
export default {
data() {
return {
people: [
{
name: 'John'
},
{
name: ''
}
]
}
},
validations: {
people: {
required,
minLength: minLength(3),
$each: {
name: {
required,
minLength: minLength(2)
}
}
}
}
}
Collection Validation
import { required } from 'vuelidate/lib/validators'
export default {
data() {
return {
username: ''
}
},
validations: {
username: {
required,
async isUnique (value) {
if (value === '') return true
const response = await fetch(`/api/unique/${value}`)
return Boolean(await response.json())
} }}
}
Asynchronous validation
Async support is provided out of the box. Just use a validator that returns a promise. Promise's success value is used for validation directly, failed promise just fails the validation and throws the error.
<div class="error" v-if="!$v.username.isUnique">This username is already registered.</div>
$v values
$v model represents the current state of validation. It does so by defining a set of properties which hold the output of user defined validation functions, following the validations option structure. The presence of those special reserved keywords means that you cannot specify your own validators with that name.
$v methods
A set of methods to control the validation model. Accessible on every level of nesting. All methods are ment to be used on any event handler you wish. There is no extra syntax to decide when the dirty flag should be set. Just use standard @input or @blur bindings.