I found an article about Validatorjs (Japanese) and tried to use it in my current project, but failed.
The reason is that I had to create complex frontend implementing the following requirements:
- Given 1:n data structure, user can dynamically add elements (e.g. multiple email)
- Do not run validation after page loaded
- After user started to input, validate only the element user is interacting
- Run validation before submitting a form.
- change the style of the element
- Show an error message just next to the element like "email address is required."
- Validation rule should be at one place, using the same logic between input and submit.
Then I found VeeValidate
.
(I wrote this article originally on April 2017. In my memory at that time VeeValidate had less than 1,000 stars, but now more than 4,000 stars. It is rapidly getting popular.)
https://github.com/logaretm/vee-validate
I would like to introduce this Great library.
Simple validation
Suppose that there is an email form and we want to run validation in the following timing:
- after user input
- before submitting the form
The code will be like this:
// VeeValidationSimple.vue
<template>
<div>
<input
name="email"
v-model="email"
v-validate="'required|email'"
:class="{'has-error': errors.has('email')}"
>
<p v-if="errors.has('email')" class="alert-danger">
{{ errors.first('email') }}
</p>
<button @click="register">Register</button>
</div>
</template>
<script>
import Vue from 'vue'
import VeeValidate from 'vee-validate'
Vue.use(VeeValidate)
export default {
data () {
return {
email: ''
}
},
methods: {
register () {
this.$validator.validateAll().then(() => {
alert('Hello, ' + this.email)
}).catch(() => {
alert(this.errors.all())
})
}
}
}
</script>
<style>
.alert-danger {
color: red;
}
.has-error {
border-color: red;
}
</style>
Promise makes the code readable.
I personally prefer that <input>
element has validation rules, because validation is an UI logic.
Multiple element validation
Multiple element validation is also easy than I expected.
Assume user can add other emails like this:
VeeValidate recognize elements by name
attribute, so we set unique name
attribute to each element. Just iteration number is OK.
// VeeValidationMultiple.vue
<template>
<div>
<!-- set unique name -->
<div v-for="(account, i) in accounts">
<input
:name="'email' + i"
v-model="account.email"
v-validate="'required|email'"
:class="{'has-error': errors.has('email' + i)}"
>
<p v-if="errors.has('email' + i)" class="alert-danger">
{{ errors.first('email' + i) }}
</p>
</div>
<p>
<button @click="addAccount">Add Account</button>
<button @click="register">Register</button>
</p>
</div>
</template>
<script>
import Vue from 'vue'
import VeeValidate from 'vee-validate'
Vue.use(VeeValidate)
export default {
data () {
return {
// v-for need Object array
accounts: [{
email: '',
}],
}
},
methods: {
addAccount () {
this.accounts.push({
email: '',
})
},
register () {
this.$validator.validateAll().then(() => {
alert('Hello, ' + this.accounts)
}).catch(() => {
alert(this.errors.all())
return false
})
}
},
}
</script>
<style>
.alert-danger {
color: red;
}
.has-error {
border-color: red;
}
</style>
Validation for the element added by user interaction works well.
Refs
VeeValidate has a great documentation. We can found validation rules easily.
- https://m.dotdev.co/form-validation-using-vue-js-2-35abd6b18c5d
- http://vee-validate.logaretm.com/index.html
Here is the source code of this article uses.
https://github.com/acro5piano/vue-cli-test/blob/master/src/components/VeeValidation.vue
Top comments (2)
There are other plugins as well for vue validation. I have used vee validate and vue-validator plugins before. I found that vee validate was really easy because I had several issues when trying to integrate vue-validator plugin.
Yeah I tried it before and thought the same!