Skip to content

Form validation in Vue.js using Vuelidate

Hello! One of the most common tasks in software development is a validation. Any app has different forms, that submit some data and we want to check numerous conditions: that fields are not empty, that they have proper format (like emails), have proper length and so on. Yes, we can do it manually, but this is not the best path. It is better to use a specific validation library. For Vue.js apps the popular choice is Vueildate. In this post we will see how to install it to your Vue apps and how to use it, as well observe most important built-in validators.

What is Vuelidate?

Let have a simple example. You’re building a signup form. You want to check that user provides a correct input, like:

  • Password has minimal length of 6 characters
  • All fields are filled
  • Email has valid format
  • etc.

You can do this manually, but it is not the best route to follow. First, is that you will find yourself in a forest of nested if-else constructs, that you most probably could not understand after a week or two. Next, even small additions will bring a lot of changes. This is always safer to rely on an external validation library. For Vue.js applications there are several choices, but one of most used is Vuelidate.

Installation

You can install Vuildate using your package manager CLI or from Vue UI’s dependencies tab. Let check how to do it using NPM:

npm install vuelidate --save

Then you need to import Vuelidate in your src/main.js to use Vuelidate globally in all app’s components:

import Vue from 'vue'
import Vuelidate from 'vuelidate'
//..

Vue.use(Vuelidate)

The last thing to do is to create validation object inside components and import required validators (will see this in next sections). You can call Vuelidate by this.$v instance.

data() function and validations object

Vueildate library uses a model-based validation. What does it mean? We need to add validation conditions to data() model fields. Yes, we can’t do this directly as data comes from Vue. Therefore, we create a new object validations. Let return to the previous example:

data() {
    return {
        signupRequest: {
            email: '',
            password: '',
            confirmPassword: '',
            firstName: '',
            lastName: ''
        }
    }
},
validations: {
    signupRequest: {
        email: {},
        password: {}.
        confirmPassword: {},
        firstName: {},
        lastName: {}
    }
}

So we have a model SignupRequest, which corresponds to data we want to send to server. We want to assert that all fields are filled and not only filled, but with specific requirements, like format or length. We create a validations object that mimimcs data model (well it does not have to copy all data model, but strictly data model you want to validate). Each field provides in square brackets validators. You can use both built-in validators or create your owns (however in this post we will follow only built-in validators).

Let say, you want to check that all fields are filled. For this we use required validator. Import it and add to validations object:

import {required} from 'vuelidate/lib/validators'
export default {
//...
data() {
    return {
        signupRequest: {
            email: '',
            password: '',
            confirmPassword: '',
            firstName: '',
            lastName: ''
        }
    }
},
validations: {
    signupRequest: {
        email: {required},
        password: {required}.
        confirmPassword: {required},
        firstName: {required},
        lastName: {required}
    }
}
//..
}

Next thing, we actually need to call Vueildate to assert conditions.

Calling Vuelidate assertions

Let create a method that will submit our signup form:

//..
methods: {
    doSignup(){

    }
}

Here we need to call Vueildate to assert specified conditions and perform a logic based on two variants:

  • Form is valid
  • Form is invalid

This is a sample implementation:

methods: {
    doSignup(){
        this.$v.$touch()
        const isInvalid = this.$v.$invalid
        if (isInvalid){
            // display error message
            alert('Please check all fields!')
        } else {
            console.log('Form is correct')
            // submit to server
        }
    }
}

This is the most general approach that touches our form and checks that all fields are valid acording to specified condtions. Although, we can validate each value separately. For example, it helps us to hightlight missed fields. The generic pattern is:

$v.[property-name].[validator]

Let say we use Bulma:

<div>
    <div class="field">
        <div class="control">
            <input class="input" v-model="email" type="email" v-bind:class="{'is-danger': !$v.email.invalid}">
        </div>
    </div>
    <div class="field">
        <div class="control">
            <input class="input" v-model="password" type="password" v-bind:class="{'is-danger': !$v.password.invalid}">
        </div>
    </div>
</div>

So, this way we can bind is-danger class to input fields, if data is missed. Next, let see most important built-in validators.

Built-in validators

From a technical point of view, validators are conditions that are used by Vuelidate to assert data model. In this section we will overview most common and used built-in validators in Vueildate.

required

We already checked this validator. It confirms that the field is non empty. It also goes to cases when the field is a string value that contains only whitespaces and also for empty arrays. It does not have any params and is very easy to use:

import {required} from 'vuelidate/lib/validators'
//..
validations: {
    //..
    firstName: {required},
    lastName: {required}
}

sameAs

In our example we have two fields password and confirmPassword, that according to the app’s logic should be equal. Of course we can do naive checking using vanila JS:

const passwordsSame = this.signupRequest.password === this.signupRequest.confirmPassword
if (passwordsSame){
    //..
} else {
    //..
}

However, Vueildate has sameAs validator that verifies an equality of the field to the given property. The code snippet below demonstates how to use sameAs:

import {required, sameAs} from 'vuelidate/lib/validators'

//..
validations: {
    signupRequest: {
        //..
        password: {required},
        confirmPassword: {
            required,
            sameAs('signupRequest.password')
        }
    }
}

NB we can combine multiple validators for the same field. For sameAs we provide as an argument a name of the property we want to be equal with – in this case it is signupRequest.password.

minLength/maxLength

This two validators assert the field’s length – either not less than (minLength) or not more than (maxLength). Both accepts as an argument an integer value of length. Works for strings and arrays.

import {minLength, maxLength, required} from 'vuelidate/lib/validators'

//..

validations: {
    SignupRequest: {
        password: {
            required, 
            minLength(6)
        },
        firstName: {
            required, 
            minLength(3), 
            maxLength(100)
        },
        lastName: {
            required, 
            minLength(3), 
            maxLength(100)
        }
    }
}

data type validators

This group inclides several validators that checks if the field is of the required data type. As an example, if we have an [invoice form](), we want to be sure that user enters only numbers in a rate or amount fields. For that we can utilize decimal and integer validators. Let observe what do we have here:

  • integer = checks that field is integer
  • decinal = checks that field is decimal
  • numeric = checks that field is numeric (both integer or decimal)
  • alpha = checks that field consists only from alphabet characters
  • alphaNum = checks that field is alpha numeric (letters and digits)

Let add a new field to our model – age. We want that it is an integer:

import {required, integer} from 'vuelidate/lib/validators'

//..

validations: {
    signupRequest: {
        //..
        age: {
            required,
            integer
        },
        password: {
            required, 
            minLength(6),
            alphaNum
        }
    }
}

email

The next validator we will observe here is email. It accepts that field is a valid email (of valid format, but it does not mean that this email actually exists – you have to find it out on server-side).

import {required, email} from 'vuelidate/lib/validators'

//...

validations: {
    SignupRequest: {
        email: {
            required, email
        }
    }
}

`

Range validators

Finally, let overview what I call as a group of range validators. It includes three functions:

  • minValue(value) = validates that the field is higher than provided value
  • maxValue(value)= validates that the field is lower than provided value
  • between(a,b) = validates that the field is between a and b values, both are included.

These validators works with numbers and dates. The code snippet below demonstates the usage of range validators:

import {required, integer, minValue, maxValue} from 'vuelidate/lib/validators'

//..

validations: {
    signupRequest: {
        //..
        age: {
            required,
            integer,
            minValue(18),
            maxValue(100)
        }
    }
}

Conclusion

In this post we talked about Vueildate – a popular validation library for Vue.js applications. We observed an installation process and how to make Vueildate work (e.g. assert data model). We also checked most common built-in validators.

References

  • Markus Oberlehner Vue.js Form Validation with Vuelidate (2018), read here
  • Sarah Drasner Form Validation in Under an Hour with Vuelidate (2019) CSS-Tricks, read here
Copy link
Powered by Social Snap