Search

Form Validation in VueJs using Vuelidate

post-title

This is a comprehensive Vue.js 2+ Form tutorial. In this tutorial, we are going to learn how to engender Forms in Vue.js from scratch and additionally going to cover how to do client-side Form validation in Vue application utilizing the Vuelidate package.
We all ken there are two types of Form validation.

Server-side form validation: It is an another way to validate HTML form data. It includes sundry input fields, text-area, numerical, string values, input length, numeric value, valid email, etc.

Client-side form validation: We validate form data before sending it to the server. In this process, we make sure that all the required form values are correctly filled.

Let’s understand what form validation is?

We often see various types of forms on almost every site we visit, and we see different kinds of messages such as:

  • This is a required field.
  • Please provide a valid email.
  • Please enter your phone number in particular format xxx-xxx-xxxx.
  • Your password should be or between 6 and 15 characters long and contain a unique set of characters.

Form validation is a simple process in which you enter data in the form and browsers makes sure whether your entered data is in the proper format or not and display either of the given above message. This entire process is known as form validation.

Getting Started with Vue.js

This tutorial guides on creating and validating a basic user form.

First, install the latest Vue CLI 4 on your local development system for working with Vue.

npm install -g @vue/cli

Download Vue project by following the below command.

vue create vue-form-validation

Get inside the project folder.

cd vue-form-validation

Use the following command to start the Vue app in the browser.

npm run serve

Create & Configure Form Component in Vue

Go to components folder and create FormValidation.vue file in it, however, you can name it anything you want and be consistent with the same file name throughout the app.

In this file we will write all the code that requires for building and validating the form.

<template>
    <div class="container" style="max-width: 500px; text-align: left">
        <div class="row">
            <div class="alert alert-success" role="alert">
                <h2 class="alert-heading">Vue Form Validation Example</h2>
            </div>
        </div>
    </div>
</template>

Next, register the file in the views template, so go to views > Home.vue and import and register the FormValidation.vue component as given below.

<template>
  <div class="home">
    <FormValidation></FormValidation>
  </div>
</template>

<script>
// @ is an alias to /src
import FormValidation from '@/components/FormValidation.vue'

export default {
  name: 'Home',
  components: {
    FormValidation
  }
}
</script>

Adding Bootstrap 4 in Vue

To create a Form, we are going to use the Bootstrap 4 UI framework. Though, there are various plugins available to integrate Bootstrap in Vue. However, we are going to add the Bootstrap via CDN in Vue.

Go to public > index.html file and add the Bootstrap CDN path in the header section.

<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet" />

Install and Configure Vuelidate in Vue App

To cover the client-side form validation, we are going to rely on Vuelidate module. The Vuelidate is a powerful, simple and lightweight model-based library which offers easy form validation for Vue.js

Here are some of the powerful features we get with Vuelidate:

  • Model-based
  • Contextified validators
  • Decoupled from templates
  • Support for nested models
  • Support for function composition
  • Support for collection validations
  • Dependency free, minimalistic library
  • Easy to use with custom validators (e.g., Moment.js)
  • Validates different data sources: Vuex getters, computed values, etc.

Run command to install Vuelidate package.

# NPM
npm install vuelidate --save


# Yarn
yarn add vuelidate

We have to import the Vuelidate library in the src/main.js file and define in the Vue.use(Vuelidate) method. This way, we can take advantage of this plugin and use it globally for all the components that require to be validated.

import Vue from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import Vuelidate from 'vuelidate'

Vue.use(Vuelidate)

Vue.config.productionTip = false

new Vue({
  router,
  store,
  render: h => h(App)
}).$mount('#app')

Build & Validate User Registration Form in Vue.js 2+ with Vuelidate

Let us create a simple form and check out the simple form validation example. We will be validating a user registration form. Go back to the FormValidation.vue file that we created at the starting of this tutorial and add the following code:

<template>
    <div class="container" style="max-width: 500px; text-align: left">

        <div class="alert alert-success" role="alert">
            <h2 class="alert-heading">Vue Form Validation Example</h2>
        </div>

        <form @submit.prevent="handleSubmit">
            <div class="form-group">
                <label for="name">Name</label>
                <input type="text" v-model="userForm.name" id="name" name="name" class="form-control"
                    :class="{ 'is-invalid': isSubmitted && $v.userForm.name.$error }" />
                <div v-if="isSubmitted && !$v.userForm.name.required" class="invalid-feedback">Name field is required</div>
            </div>

            <div class="form-group">
                <label for="email">Email</label>
                <input type="email" v-model="userForm.email" id="email" name="email" class="form-control"
                    :class="{ 'is-invalid': isSubmitted && $v.userForm.email.$error }" />
                <div v-if="isSubmitted && $v.userForm.email.$error" class="invalid-feedback">
                    <span v-if="!$v.userForm.email.required">Email field is required</span>
                    <span v-if="!$v.userForm.email.email">Please provide valid email</span>
                </div>
            </div>

            <div class="form-group">
                <label for="mobile">Mobile</label>
                <input type="text" v-model="userForm.mobile" id="mobile" name="mobile" class="form-control"
                    :class="{ 'is-invalid': isSubmitted && $v.userForm.mobile.$error }" />
                <div v-if="isSubmitted && $v.userForm.mobile.$error" class="invalid-feedback">
                    <span v-if="!$v.userForm.mobile.required">Mobile field is required</span>
                </div>
            </div>

            <div class="form-group">
                <label for="gender">Gender</label>
                <div class="form-group" :class="{ 'is-invalid': isSubmitted && $v.userForm.gender.$error }">
                    <div class="form-check form-check-inline" :class="{ 'is-invalid': isSubmitted && $v.userForm.gender.$error }">
                        <input class="form-check-input" type="radio" name="gender" v-model="userForm.gender" id="gender1" value="male">
                        <label class="form-check-label" for="gender1">Male</label>
                    </div>
                    <div class="form-check form-check-inline" :class="{ 'is-invalid': isSubmitted && $v.userForm.gender.$error }">
                        <input class="form-check-input" type="radio" name="gender" v-model="userForm.gender" id="gender2" value="female">
                        <label class="form-check-label" for="gender2">Female</label>
                    </div>

                    <div v-if="isSubmitted && $v.userForm.gender.$error" class="invalid-feedback">
                        <span v-if="!$v.userForm.gender.required">This field is required</span>
                    </div>                    
                </div>
            </div>

            <div class="form-group">
                <label for="password">Password</label>
                <input type="password" v-model="userForm.password" id="password" name="password" class="form-control"
                    :class="{ 'is-invalid': isSubmitted && $v.userForm.password.$error }" />
                <div v-if="isSubmitted && $v.userForm.password.$error" class="invalid-feedback">
                    <span v-if="!$v.userForm.password.required">Password field is required</span>
                    <span v-if="!$v.userForm.password.minLength">Password should be at least 5 characters long</span>
                </div>
            </div>

            <div class="form-group">
                <label for="confirmPassword">Confirm Password</label>
                <input type="password" v-model="userForm.confirmPassword" id="confirmPassword" name="confirmPassword"
                    class="form-control" :class="{ 'is-invalid': isSubmitted && $v.userForm.confirmPassword.$error }" />
                <div v-if="isSubmitted && $v.userForm.confirmPassword.$error" class="invalid-feedback">
                    <span v-if="!$v.userForm.confirmPassword.required">Confirm Password field is required</span>
                    <span v-else-if="!$v.userForm.confirmPassword.sameAsPassword">Passwords should be matched</span>
                </div>
            </div>

            <div class="form-group form-check">
                <input type="checkbox" v-model="userForm.accept" @change="$v.userForm.accept.$touch()" id="accept" class="form-check-input">
                <label class="form-check-label" :class="{ 'is-invalid': isSubmitted && $v.userForm.accept.$error }" for="accept">Accept terms &nbsp; conditions</label>

                <div v-if="isSubmitted && $v.userForm.accept.$error" class="invalid-feedback">
                    <span v-if="!$v.userForm.accept.required">Accept terms and conditions</span>
                </div>
            </div>

            <div class="form-group">
                <button class="btn btn-danger btn-block">Register</button>
            </div>
        </form>
        
    </div>
</template>

<script>
    import {
        required,
        email,
        minLength,
        sameAs
    } from "vuelidate/lib/validators";

    export default {
        data() {
            return {
                userForm: {
                    name: "",
                    email: "",
                    mobile: "",
                    gender: "",
                    password: "",
                    confirmPassword: "",
                    accept: ""
                },
                isSubmitted: false
            };
        },
        validations: {
            userForm: {
                name: {
                    required
                },
                email: {
                    required,
                    email
                },
                mobile: {
                    required
                },
                gender: {
                    required
                },
                password: {
                    required,
                    minLength: minLength(5)
                },
                confirmPassword: {
                    required,
                    sameAsPassword: sameAs('password')
                },
                accept: {
                    required (val) {
                      return val
                    }
                }
            }
        },
        methods: {
            handleSubmit() {
                this.isSubmitted = true;

                this.$v.$touch();
                if (this.$v.$invalid) {
                    return;
                }

                alert("SUCCESS!" + JSON.stringify(this.userForm));
            }
        }
    };
</script>

<style lang="scss">
.form-group > label {
    font-weight: 600;
}
</style>

Let us break it down everything we did in the above Form template, and we tried to cover the validation for the name, email, mobile number, gender, password, and password match form fields in the Vue validation example.

We imported teh Vuelidate’s validators inside the script tag like required, email, minLength, and sameAs.

We used the v-model with HTML input fields; this model bind user object properties with the app component data.

Validation properties are set inside the validations: { } object inside the Vue component. The validations property creates an object inside the $v: Object. It can be accessed using the Vue DevTools: