Vue 2 Tutorial-How To Add Form Validation In Vue 2 With Vuelidate

This Vue 2 tutorial will teach us how to create Forms in Vue.js from scratch and cover how to do client-side Form Validation in vue Applications using the Vuelidate package.

Vue Form Validation Tutorial

 

There are two types of Form Validations:

Server-side Form Validations: In this type of form validation, we validate HTML form data. It includes various input fields, text area, numerical, string values, input length, numeric value, valid email, etc.

Client-side Form Validation: In this type, we validate form data before sending it to the server. This process ensures that all the required form values are correctly filled.

Now, let’s understand what Form Validation is.

We often see various types of forms on almost every site we see 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 just a simple process in which you enter data in the form and browsers make sure whether your entered data is in the proper format or not and not display either of the given above messages. This complete process is called Form Validation.

Let’s learn the process of Form Validation step-by-step now:

Getting Started With Vue.js

This tutorial guides how to create and validate a basic user form.

First of all, we have to install the latest version of Vue CLI 4 on our local development system for working with Vue:

npm install -g @vue/cli

Now, we will download the Vue project by using the below command:

vue create vue-form-validation

Further, we get inside the project folder:

cd vue-form-validation

 

Error: digital envelope routines::unsupported
opensslErrorStack: [ 'error:03000086:digital envelope routines::initialization error' ],
library: 'digital envelope routines',
reason: 'unsupported',
code: 'ERR_OSSL_EVP_UNSUPPORTED'

 

To remove the above error for invoking the app, we have to make sure to update the “scripts”: [] array in the package.json file:

"scripts": {
    "serve": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service serve",
    "build": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service build",
    "lint": "export NODE_OPTIONS=--openssl-legacy-provider && vue-cli-service lint"
},

 

Vue Multi-word Error

To remove the multi-word error, we will add the following code in the vue.config.js file:

const { defineConfig } = require('@vue/cli-service')
module.exports = defineConfig({
  transpileDependencies: true,
  lintOnSave: false,
})

Then, we need to use the below command to start the vue app in the browser:

npm run serve

 

Create & Configure Form Component In Vue

Here, we will go to the components folder and create FormValidation.vue file in it. However, we can name it anything we 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>

 

Afterward, we have to register the file in the views template. So, we will go to the 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 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 will add Bootstrap via CDN in Vue.

Then, we have to 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 Vuelidation In Vue App

To cover the client-side form validation, we are going to rely on the Vuelidate module:

The Vuelidate is a powerful, simple and lightweight model-based library that offers easy form validation for Vue.js.

Below are some of the powerful features that we get with Vuelidate:

  • Model-based
  • Contextified validators
  • Decoupled from templates
  • 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.

Now, we will run the given command to install the 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 it 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 And Validate User registration Form In Vue.js 2+ With Vuelidate

Now, we need to create a simple form and check out the simple form validation example. We will be validating a user registration form. Then, we go back to the FormValidation.vue file that we created at the start of this tutorial and add the given 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   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 now break 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 fields in the Vue validation example.

We imported the vuelidate’s validators inside the script tag like the 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 et 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:

Vue Vuelidate Form Validation Example

 

We can bind the main form with submitting events using the handleSubmit() method.

We are showing the validation error messages when the user is done clicking on the form’s submit button.

 

Leave a Reply

Your email address will not be published. Required fields are marked *