View.js form validation

by | 23 Jan 2019 | Architecture & technos

Validation is a very common task in web applications. Indeed, data needs to be validated before submitting a form and before it is written into a database or passed to a web service.

This article deals with form validation in Vue.js and especially three plugins that perform this task: Simple Vue Validator, VeeValidate and Vuelidate.

By reading this article, we will be able to test the code snippets thanks to this github repository, a simple Vue.js project built with official Vue.js.

In this project, there are validations for every plugin on a classic user form composed of:
- Two required text fields representing the firstname and the lastname of the user with a minimum length constraint
- A required email field
- An optional birth date field
- Two required fields with constraints on length to set and confirm a password

For every plugin, there will be a basic usage using the previous required mail field and then, a comparison will be made to highlight the benefits and drawbacks of each plugin.

Single View Validator

Simple Vue Validator is a Vue.js 2.0 plugin that allows to validate input fields and display errors thanks to a model-based solution for monitoring user input.

Installation and configuration

First, install the package via npm or yarn.

npm install — save simple-vue-validator
yarn add simple-vue-validator

Then, add the library to enable it globally on the Vue.js app.

// main.js
import Vue from ‘vue’;
import SimpleVueValidation from ‘simple-vue-validator’;
Vue.use(SimpleVueValidation);

Form validation example

To validate an email field, let's consider a specific component named TestSimpleVueValidator.vue.

// TestSimpleVueValidator.vue
<template>
  <div id="testSimpleVueValidator">
    <form @submit.prevent="onSubmit()">
      <div>
        <label for="userMail">Mail</label>
        <input id="userMail" v-model.trim="mail" :class="{error: validation.hasError('mail'), valid: validation.isTouched('mail') && !validation.hasError('mail')}"/>
      </div>
      <div class="error" v-if="validation.hasError('mail')">
        {{ validation.firstError('mail') }}
      </div>
     <button type="submit" :disabled="validation.countErrors() > 0">Submit</button>
    </form>
  </div>
</template>
<script>
  import { Validator } from 'simple-vue-validator';
  export default {
    name: 'TestSimpleVueValidator',
    data() {
      return {
        mail: '',
      };
    },
    validators: {
      mail(value) {
        return Validator.value(value).required().email();
      },
    },
    methods: {
      onSubmit() {
        this.$validate()
        .then((success) => {
          if (success) {
            // Do something
          }
        });
      },
    },
  };
 </script>

How does form validation works with Simple Vue Validator ?

Firstly, validation rules have to be written in validators object, the element that contains all the validation logic. Every rule needs to return a boolean value and uses the Validator class provided by the plugin. As we can see, there are built-in rules but it is also possible to write custom ones for more complex logic.

Secondly, we have to display the potential errors. By providing the validators object to our component instance, a ValidationBag instance named validation is added to our component. Thanks to this component, we will be able to display validation result, detect if input has been made by the user, etc.

Finally, in the same way, the library adds the $validate method to our component instance when we provide the validators object to our component. When submitting our form, we have to call $validate method to execute all the validators in order to ensure that data is correct before using it.

To have a more detailed usage, take a look at TestSimpleVueValidator component.

VeeValidate

VeeValidate is a plugin for Vue.js, inspired by PHP Framework Laravel's validation syntax, that allows to validate input fields and display errors by injecting the validation rules directly into the HTML.

Installation and configuration

First, install the package via npm or yarn.

npm install — save simple-vuelidate
yarn add simple-vuelidate

Then, add the library to enable it globally on the Vue.js app.

// main.js
import Vue from ‘vue’;
import Vuelidate from ‘vuelidate’;
Vue.use(Vuelidate);

Form validation example

To validate an email field, let's consider a specific component named TestVuelidate.vue.

// TestVuelidate.vue
<template>
  <div id="testVuelidate">
    <form @submit.prevent="onSubmit()">
      <div>
        <label for="userMail">Mail</label>
        <input id="userMail" v-model.trim="mail" @input="$v.mail.$touch" :class="{error: $v.mail.$error, valid: $v.mail.$dirty && !$v.mail.$invalid}"/>
      </div>
      <div class="error" v-if="$v.mail.$dirty && !$v.mail.required">
        Mail is required
      </div>
      <div class="error" v-if="$v.mail.$dirty && !$v.mail.email">
        Mail is not valid
      </div>
      <button type="submit" :disabled="$v.$invalid">Submit</button>
    </form>
  </div>
</template>
<script>
  import { required, email } from 'vuelidate/lib/validators';
  export default {
    name: 'TestVuelidate',
    data() {
      return {
        mail: '',
      };
    },
    validations: {
      mail: {
        required,
        email,
      },
    },
    methods: {
      onSubmit() {
        if (this.$v.$invalid) return;
        // Do something
      },
    },
  };
</script>

How does form validation works with Vuelidate ?

There are two distinct structures present in Vuelidate:
- validations component options to define the entire form validation
- $v structure, an object in our viewmodel that holds the validation state

For each value that needs to be validated, we have to create a key inside validations options with specific rules. Vuelidate comes with a set of builtin validators we can just require and use but we can easily write custom validators and combine them with builtin ones.

Then, we can display errors by using the $v model that represents the current state of validation. Error messages are not provided by the plugin in order to let us choose the way we render them.

With $v model, we can access the current state of validation for a specific field but also check the validity of the entire form. Thus, when submitting our form, we are able to ensure that data is correct and ready to use.

To see a more complex example, go and see TestVuelidate component.

Comparison

The following comparison between these three plugins is not intended to define which one needs to be used but to provide enough information to help identify the most appropriate plugin to use.

Each plugin has good and easy-to-use support documentation but I believe that VeeValidate one is the clearest with many examples on how to use each feature.

Some numbers

All these plugins are correctly maintained since new features come regularly - between three and six months.

VeeValidate seems to be the most popular plugin with more than 5 000 stars on Github and more than 40 000 weekly downloads on npm at the moment this post is written.

Vuelidate is also very used with more than 20 000 weekly downloads on npm and more than 2 500 stars on Github.

Finally, Simple Vue Validator has only about 200 stars on Github and is downloaded about 1,000 times each week on npm.

Built-in and custom rules

VeeValidate comes with 34 validation rules against about 20 for Simple Vue Validator and Vuelidate. Most of these rules allow classic validation on numbers or strings but we can notice that Simple Vue Validator does not provide any rule for date validation.

Each plugin allows the use to create its custom rules or to extend existing ones by updating translations for instance.

Localization management is possible only with VeeValidate thanks to a range of more than 40 supported locales whereas Simple Vue Validator only provides English error messages.

Vuelidate does not manage translations since it does not provide any built-in error message. Hence, the user has to manage translations in a traditionnal way.

More features

Simple Vue Validator, VeeValidate and Vuelidate allow an asynchronous validation to work with promises and it is also possible to make delayed validations.

To improve user experience, each plugin provides about ten flags to customize the render of the component but I believe that the VeeValidate ones are simpler to use.

If you have other questions related to Vue.js, don't hesitate to comment down below, and we'll try our best to answer quickly and if you are interested in other articles about Vue.js be sure to tell us!

Quentin

Quentin

Developer @theTribe

Why don't we talk?