While the most beginner-friendly approach to form validation in Vue.js might be through template-based forms, a much more flexible way is to validate the model instead. Model-based validation tends to be easier to understand and change for larger apps, moving the visual clutter from the template to the model and reducing it significantly. The most well-known library to accomplish this in Vue is through Vuelidate.
As usual, Vuelidate can be installed from NPM or Yarn.
# Yarn
$ yarn add vuelidate
# NPM
$ npm install vuelidate --save
Then, in your app bootstrap, enable the Vuelidate plugin.
import Vue from 'vue';
import Vuelidate from 'vuelidate';
import App from 'App.vue';
Vue.use(Vuelidate);
new Vue({
el: '#app',
render: h => h(App)
});
To validate fields, add a definition object for properties in your data model to the validations property of your component. Then import validation functions from vuelidate/lib/validations (or custom ones you create). You will then be able to bind to the data property via v-model as usual. Validation information will be stored in this.$v[propertyName].
$v’s Schema:
$v[propertyName]: {
$dirty: boolean, // Whether or not this field has been interacted with yet.
$invalid: boolean, // If this field is current valid or invalid, regardless of whether or not it is "dirty"
$error: boolean, // Shortcut for $invalid && $dirty
$pending: boolean, // Whether or not there is a pending validation (for async validations)
$each: object // Holds all the validations for looped models.
[YourValidationName]: boolean // The state of the validations defined on this property validations. (ie. if you have the 'required' validator, there would be a boolean 'required' property here, and so forth.)
[Nested]: object // You can nest values in your model here as well, and the validation properties will be added to each nested field.
}
<template>
<form>
<input type="text" v-model="emailValue"/>
<p v-if="!$v.emailValue.required">The email field is required!</p>
<p v-if="!$v.emailValue.email">The input must be a proper email!</p>
</form>
</template>
<script>
import { required, email } from 'vuelidate/lib/validations'
export default {
data() {
return {
emailValue: ''
}
},
validations: {
emailValue: {
required,
email
}
}
}
</script>
Vuelidate provides these validators by default. They can be imported from vuelidate/lib/validators. If you’re using Webpack 2 or Rollup with tree shaking, any validators not used in your project will not be bundled with it.
A custom validator in Vuelidate is simply a function that returns a boolean or a promise that resolves to a boolean.
If you want to ensure that fields contain only the word “tom”, you might write a validator like this.
export const TomValidator = (value, component) => {
return value === 'tom';
}
...
<script>
import { TomValidator } from './tom-validator';
export default {
data() {
return {
inputField: ''
}
},
validators: {
inputField: {
TomValidator
}
}
}
</script>
You might want to go a step further and allow a string to be specified that must be matched. In that case, just create a higher-order function that returns the validator function, like so.
export const MatchValidator = (stringToMatch) => {
return (value, component) => value === stringToMatch;
}
...
<script>
import { MatchValidator } from './match-validator';
export default {
data() {
return {
inputField: ''
}
},
validators: {
inputField: {
MatchValidator: MatchValidator('rupert')
// Only allows inputField to contain 'rupert.' One might Wonder why the field even exists then...
}
}
}
</script>
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
While we believe that this content benefits our community, we have not yet thoroughly reviewed it. If you have any suggestions for improvements, please let us know by clicking the “report an issue“ button at the bottom of the tutorial.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!