Vue.js 2 + VeeValidate + BootstrapVue – Form Validation Example

Last updated on by Digamber
The purpose of web form validation is to make sure that the user-produced required and adequately formatted information to perform a specific task.

In this tutorial, we will learn how to create a responsive web form using the BootstrapVue front-end CSS library and validate that Form using the Template-Driven approach using VeeValidate Form Validation Framework.

Vue Form Validation Example

The template-driven approach is nothing but the simple way which allows you to validate your forms by combining attributes to inputs. This can be very easily achieved in Vue by taking the help of vee-validate package.

Why Form Validation Needed?
Form validation is essential to protect forms by sending abusive emails by malicious users. Incorrect submission of form data may lead to a breach of security.

Non validated forms may invite hackers to attacks using header injections, cross-site scripting, and SQL injections methods.

We are going to build a simple user registration form with necessary input fields such as name, email, mobile number, city, password, confirm password, and hobbies.

In this form, every field will be a required field along with that we will have email validation and password confirmation validation applied to the input fields.

To add the styling, we used a bootstrap-vue package, which is an alternative to Bootstrap 4 for the Vue environment.

Install VeeValidate

To install vee-validate package, run either of the commands among Yarn or NPM package manager.

# NPM
npm install vee-validate --save


# Yarn
yarn add vee-validate

Next, open your main.js file and add the following code inside of it to initiate the vee-vulidate package.

import { ValidationObserver, ValidationProvider, extend } from 'vee-validate';
import * as rules from 'vee-validate/dist/rules';

// install rules
Object.keys(rules).forEach(rule => {
  extend(rule, rules[rule]);
});

Vue.component('ValidationObserver', ValidationObserver);
Vue.component('ValidationProvider', ValidationProvider);

Adding Bootstrap in Vue

Adding Bootstrap 4 in the Vue application is easy. We have to run the given below command to add the BootstrapVue plugin.

npm i bootstrap-vue

BootstrapVue, with over 40 available plugins, more than 80 custom components, and over 530 icons, provides one of the most comprehensive implementations of the Bootstrap v4 component and grid system for Vue.js, complete with extensive and automated WAI-ARIA accessibility markup.

Next, again go to main.js file and add the Bootstrap required services to enable the plugin.

import Vue from "vue";
import { ValidationObserver, ValidationProvider, extend } from 'vee-validate';
import * as rules from 'vee-validate/dist/rules';
import App from "./App.vue";

import BootstrapVue from 'bootstrap-vue';
import 'bootstrap/dist/css/bootstrap.css';
import 'bootstrap-vue/dist/bootstrap-vue.css';

// install rules
Object.keys(rules).forEach(rule => {
  extend(rule, rules[rule]);
});

// Install components globally
Vue.use(BootstrapVue);
Vue.component('ValidationObserver', ValidationObserver);
Vue.component('ValidationProvider', ValidationProvider);

Vue.config.productionTip = false;

new Vue({
  render: h => h(App)
}).$mount("#app");

Create Form with Bootstrap in Vue

In this step, we are going to create a basic form. Let us add the following code inside the Vue template. This code contains the HTML code that will display the beautiful and user-centric form on the user’s browser.

<template>
    <b-form @submit.prevent="handleSubmit">

        <b-form-group label="Name">
            <b-form-input
              type="text"
              v-model="user.name"
              placeholder="Enter name">
            </b-form-input>
        </b-form-group>

        <b-form-group label="Email">
            <b-form-input
              type="email"
              v-model="user.email"
              placeholder="Enter email">
            </b-form-input>
        </b-form-group>

        <b-form-group label="Mobile">
            <b-form-input
              type="text"
              v-model="user.mobile"
              placeholder="Enter mobile no">
            </b-form-input>
        </b-form-group>

        <b-form-group label="City">
          <b-form-select v-model="user.city">
            <option value="">Choose</option>
            <option value="CA">Los Angeles</option>
            <option value="IL">Chicago</option>
            <option value="LA">New Orleans</option>
            <option value="NM">Santa Fe</option>
          </b-form-select>
        </b-form-group>

        <b-form-group label="Password">      
            <b-form-input v-model="user.password" type="password" placeholder="Enter password">
            </b-form-input>
        </b-form-group>

        <b-form-group label="Confirm Password">
            <b-form-input v-model="user.confirmation" type="password"></b-form-input>
        </b-form-group>

        <b-form-group>
          <b-form-checkbox-group v-model="user.hobbies">
            <b-form-checkbox value="Reading">Reading</b-form-checkbox>
            <b-form-checkbox value="Gyming">Gyming</b-form-checkbox>
            <b-form-checkbox value="Movies">Movies</b-form-checkbox>
          </b-form-checkbox-group>
        </b-form-group>

      <b-button block type="submit" variant="primary">Submit</b-button>
    </b-form>
</template>

<script>
export default {
  data: () => ({
    user:{
        name: '',
        email: '',
        mobile: '',
        city: '',
        password: '',
        confirmation: '',
        hobbies: []
    }
  }),
  methods: {
    handleSubmit () {
      console.log(this.user);
    }
  }
};
</script>

<style lang="scss">
form {
   max-width: 500px;
   margin: 0 auto; 
   text-align: left;
}
.col-form-label {
    font-weight: 600;
}
</style>

Create Form with Bootstrap in Vue

Vue Form Validation with VeeValidate

We already registered the ValidationProvider in main.js file, and It acts as a validator for your fields, it works via scoped-slots to provide validation errors to your template.

The v-model directive bind input field properties with user form object in the Vue app. The VeeValidate plugin made the Template-Driven approach easy to be added with rules.

Rules support a lot of standard validators that are sufficient to add validation like min, max, image, alpha, email, size, required, regex, numeric integer, and many more.

We bind the handleSubmit() method with submitting event something like this @submit.prevent=”handleSubmit” event.

Here, prevent method cancels the event if it is cancelable, meaning that the default action that belongs to the event will not occur.

Initially, we are showing the Validation messages when the user clicks on the submit button.

<template>
<ValidationObserver ref="observer">
    <b-form slot-scope="{ validate }" @submit.prevent="validate().then(handleSubmit)">
      <ValidationProvider rules="required" name="Name">
        <b-form-group slot-scope="{ valid, errors }" label="Name">
            <b-form-input
              type="text"
              v-model="user.name"
              :state="errors[0] ? false : (valid ? true : null)"
              placeholder="Enter name">
            </b-form-input>
            <b-form-invalid-feedback>
              {{ errors[0] }}
            </b-form-invalid-feedback>
        </b-form-group>
      </ValidationProvider>

      <ValidationProvider rules="required|email" name="Email">
        <b-form-group 
          slot-scope="{ valid, errors }"
          label="Email">
            <b-form-input
              type="email"
              v-model="user.email"
              :state="errors[0] ? false : (valid ? true : null)"
              placeholder="Enter email">
            </b-form-input>
            <b-form-invalid-feedback>
              {{ errors[0] }}
            </b-form-invalid-feedback>
        </b-form-group>
      </ValidationProvider>

      <ValidationProvider rules="required" name="Mobile">
        <b-form-group 
          slot-scope="{ valid, errors }"
          label="Mobile">
            <b-form-input
              type="text"
              v-model="user.mobile"
              :state="errors[0] ? false : (valid ? true : null)"
              placeholder="Enter mobile no">
            </b-form-input>
            <b-form-invalid-feedback>
              {{ errors[0] }}
            </b-form-invalid-feedback>
        </b-form-group>
      </ValidationProvider>

      <ValidationProvider name="City" rules="required">
        <b-form-group slot-scope="{ valid, errors }" label="City:">
          <b-form-select 
            :state="errors[0] ? false : (valid ? true : null)" 
            v-model="user.city">
            <option value="">Choose</option>
            <option value="CA">Los Angeles</option>
            <option value="IL">Chicago</option>
            <option value="LA">New Orleans</option>
            <option value="NM">Santa Fe</option>
          </b-form-select>
            <b-form-invalid-feedback>
              {{ errors[0] }}
            </b-form-invalid-feedback>
        </b-form-group>
      </ValidationProvider>

      <ValidationProvider rules="required" name="Password" vid="password">
        <b-form-group 
          slot-scope="{ valid, errors }"
          label="Password">      
            <b-form-input
              type="password"
              v-model="user.password"
              :state="errors[0] ? false : (valid ? true : null)"
              placeholder="Enter password">
            </b-form-input>
            <b-form-invalid-feedback>
              {{ errors[0] }}
            </b-form-invalid-feedback>
        </b-form-group>
      </ValidationProvider>

      <ValidationProvider rules="required|confirmed:password" name="Confirm Password">
        <b-form-group 
          slot-scope="{ valid, errors }"
          label="Confirm Password">
            <b-form-input
              type="password"
              v-model="user.confirmation"
              :state="errors[0] ? false : (valid ? true : null)">
            </b-form-input>
            <b-form-invalid-feedback>
              {{ errors[0] }}
            </b-form-invalid-feedback>
        </b-form-group>
      </ValidationProvider>

      <ValidationProvider name="Hobbies" rules="required|length:1">
        <b-form-group slot-scope="{ valid, errors }">
          <b-form-checkbox-group 
            :state="errors[0] ? false : (valid ? true : null)" 
            v-model="user.hobbies">
            <b-form-checkbox value="Reading">Reading</b-form-checkbox>
            <b-form-checkbox value="Gyming">Gyming</b-form-checkbox>
            <b-form-checkbox value="Movies">Movies</b-form-checkbox>
          </b-form-checkbox-group>
          <b-form-invalid-feedback>
            {{ errors[0] }}
          </b-form-invalid-feedback>
        </b-form-group>
      </ValidationProvider>

      <b-button block type="submit" variant="primary">Submit</b-button>
    </b-form>
</ValidationObserver>
</template>

<script>
import { ValidationObserver, ValidationProvider } from 'vee-validate';

export default {
  components: {
    ValidationObserver,
    ValidationProvider
  },
  data: () => ({
    user:{
        name: '',
        email: '',
        mobile: '',
        city: '',
        password: '',
        confirmation: '',
        hobbies: []
    }
  }),
  methods: {
    handleSubmit () {
      console.log(this.user);
    }
  }
};
</script>

<style lang="scss">
form {
   max-width: 500px;
   margin: 0 auto; 
   text-align: left;
}
.form-group > label {
    font-weight: 600;
}
</style>

Vue Form Validation with VeeValidate

Summary

We just learned to create Forms in Vue and also looked at how to add validation using vee-validate plugin. It makes validating HTML inputs and Vue components super easy.

You can get the complete code of this tutorial on this GitHub repo.