Vuelidate

What it is: A library that handles input validations for apps using the Vue framework.

How it's built: Vuelidate is an open source library written in JavaScript and maintained by a small team of developers.

How to use it: Install the npm pacakage, then import the library into your Vue app globally or on a component-by-component basis as a mixin. The vuelidate github page has a getting-started readme and their official page has more thorough documentation.

THE PROGRAM

We all need forms. Forms for searching. Forms for submitting payments. Forms for creating an account. Forms for configuring settings. Forms for generating forms for filling out forms about other forms. Forms all the way down.

Email cannot be blank. Phone number must be 10 digits. Username is already taken. These are validations. The form has to impose some sort of structure on the data before it is submitted. In some cases this validation is simple – Password must be at least 8 characters. But validations can also get complex. You must choose at least one but no more than four options. Setting X cannot be applied if setting Y is turned on. And the considerations about how to handle validations can also get very complex. Should validations be applied on keystroke? Or on leave? Or when the user clicks submit? How should invalid fields be displayed? Does the styling of the form make it easy or difficult for the user to submit valid data?

I work on an app that uses lots of forms, and Vuelidate is the library that handles our validations. You make vuelidate work by declaring a validations object within your component, and then listing the fields you want to validate as keys inside the object. Like so:

export default {
  data() {
    return {
      username: ''
    }
  },

  validations: {
    return {
      username: required
    }
  }
}

Here we are using the most common validation -- required which is one of many built in to the library. The meaning of the code is pretty straightforward: we have a reactive data element, username, and the form is considered invalid unless that element has a value. The library currently comes with 22 built in validators, like minLength and url, that can be great time savers and cover a lot of use cases. The validations object is accessible within your component as $v and acts like any other computed object. It has a very nice api with methods like $anyError and $invalid that make it easy to derive useful behavior from your validations. Wanna highlight a text box with a red border if the user forgot to enter a username? class="{'field-error': $v.username.$error }". Wanna disable the submit button until all validations are met? $v.$anyError makes it so easy.

The most interesting part of the library is its support for custom validators. If you have a lot of forms you will eventually have needs beyond the 22 out-of-the-box validations. Once you get a hang of the structure of the validations object in your code, it’s pretty intuitive to build your custom validation. For example, I was working on a component where the reactive data element was an object, and I needed to check that at least one of the object's properties had a truthy value. So I built a simple javascript function:

function objectHasTruthyValue (obj) {
  return Object.keys(obj).some(k => obj[k] === true)
}

At this point I COULD just include that function within my component and call it inside the validators block, like in the basic example above. OR EVEN BETTER -- I can add it to a customValidators.js file and then import it into all the components that need it. The result looks like this:

import { objectHasTrueValue }  from '../helpers/customValidators.js'

...(rest of the component omitted)

validations () {
  return {
    username: required,
    userAttributes: { objectHasTrueValue }
  }
}
        

In time I can build a useful library of validators that are specific to my needs and can be dropped into any of my components.

Vuelidate has been a pleasantly useful tool for simplifying a set of common tasks -- exactly what a library should be. Thanks for reading!