Vue.js + VeeValidate - Form Validation Example

Example built with Vue 2.5.2 and VeeValidate 2.1.0

Other versions available:

This is a quick example of how to setup form validation in Vue.js with the VeeValidate library. The example is a simple registration form with pretty standard fields for first name, last name, email and password. All fields are required, plus the email field must be a valid email address and the password field must have a min length of 6.

I've setup the form to validate on submit rather than as soon as each field is changed, this is implemented with a submitted field in the app component that is set to true when the form is submitted for the first time.

Styling of the Vue.js + VeeValidate example is all done with Bootstrap 4 CSS.

Here it is in action: (See on CodeSandbox at

Vue.js + VeeValidate Form Validation App Component

The app component template contains all the html markup for displaying the example registration form in your browser. The form input fields use the v-model attribute to bind to properties of the user object in the app component data. Validation is implemented using the v-validate attribute from the VeeValidate library, it supports a bunch of validators out of the box including required, minlength and email.

The form binds the submit event to the handleSubmit(e) method in the app component using the Vue event binding @submit.prevent="handleSubmit", .prevent prevents the default browser form submit behaviour (equivalent of putting e.preventDefault() in the handleSubmit method).

Validation messages are displayed only after the user attempts to submit the form for the first time, this is controlled with the submitted data property of the app component.

  <div class="jumbotron">
      <div class="container">
          <div class="row">
              <div class="col-sm-8 offset-sm-2">
                      <h2>Vue.js Form Validation</h2>
                      <form @submit.prevent="handleSubmit">
                          <div class="form-group">
                              <label for="firstName">First Name</label>
                              <input type="text" v-model="user.firstName" v-validate="'required'" id="firstName" name="firstName" class="form-control" :class="{ 'is-invalid': submitted && errors.has('firstName') }" />
                              <div v-if="submitted && errors.has('firstName')" class="invalid-feedback">{{ errors.first('firstName') }}</div>
                          <div class="form-group">
                              <label for="lastName">Last Name</label>
                              <input type="text" v-model="user.lastName" v-validate="'required'" id="lastName" name="lastName" class="form-control" :class="{ 'is-invalid': submitted && errors.has('lastName') }" />
                              <div v-if="submitted && errors.has('lastName')" class="invalid-feedback">{{ errors.first('lastName') }}</div>
                          <div class="form-group">
                              <label for="email">Email</label>
                              <input type="email" v-model="" v-validate="'required|email'" id="email" name="email" class="form-control" :class="{ 'is-invalid': submitted && errors.has('email') }" />
                              <div v-if="submitted && errors.has('email')" class="invalid-feedback">{{ errors.first('email') }}</div>
                          <div class="form-group">
                              <label for="password">Password</label>
                              <input type="password" v-model="user.password" v-validate="{ required: true, min: 6 }" id="password" name="password" class="form-control" :class="{ 'is-invalid': submitted && errors.has('password') }" />
                              <div v-if="submitted && errors.has('password')" class="invalid-feedback">{{ errors.first('password') }}</div>
                          <div class="form-group">
                              <button class="btn btn-primary">Register</button>

export default {
    name: 'app',
    data () {
        return {
            user: {
                firstName: '',
                lastName: '',
                email: '',
                password: ''
            submitted: false
    methods: {
        handleSubmit(e) {
            this.submitted = true;
            this.$validator.validate().then(valid => {
                if (valid) {
                    alert('SUCCESS!! :-)\n\n' + JSON.stringify(this.user))

Vue.js + VeeValidate Form Validation Base Vue Instance

There isn't much going on in the base Vue instance other than the standard stuff. Validation is configured on the Vue instance by importing VeeValidate and calling Vue.use(VeeValidate);.

The options passed to the Vue instance tell it to render the App component inside the #app html element.

import Vue from "vue";
import VeeValidate from "vee-validate";

import App from "./app/App";


new Vue({
  el: "#app",
  render: h => h(App)


Subscribe or Follow Me For Updates

Subscribe to my YouTube channel or follow me on Twitter, Facebook or GitHub to be notified when I post new content.

Other than coding...

I'm currently attempting to travel around Australia by motorcycle with my wife Tina on a pair of Royal Enfield Himalayans. You can follow our adventures on YouTube, Instagram and Facebook.

Need Some Vue Help?

Search fiverr to find help quickly from experienced Vue developers.

Supported by