VeeValidate is useful for Vue.js frontend validation
Tags: vue, veevalidate
Published: 2018-04-25 11:02:34

---
title: VeeValidate is useful for Vue.js frontend validation
published: true
description: 
tags: vuejs, veevalidate
---

I found [an article about Validatorjs (Japanese)](http://qiita.com/hirohero/items/e51ff5a98a0eea425d44) 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

![out.gif](https://qiita-image-store.s3.amazonaws.com/0/103885/82eaf966-31b9-2bf5-a2d0-e61d86406074.gif)


The code will be like this:

```jinja

// 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:

![out.gif](https://qiita-image-store.s3.amazonaws.com/0/103885/64ed17cc-96bc-29ca-59f1-1322a19a12f8.gif)

VeeValidate recognize elements by `name` attribute, so we set unique `name` attribute to each element. Just iteration number is OK.

```jinja

// 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