Vue Props Validation

Passing data down through component props is a common Vue pattern. How do we validate props & what are some best-practices when using them? 🧐

In this tutorial, we will cover best-practices props validation and things to watch out for when passing data down from one component to another.

Overview

Let's have a look at the bigger picture first and then dig deeper. 😎

All Kind Of Props

A long list of props with all sort of validation criteria:

  props: {
    
    luckyNumber: Number,
    
    flexibleProp: [String, Number],
    
    name: {
      type: String,
      required: true
    },
    
    percentage: {
      type: Number,
      default: 100
    },
    
    profile: {
      type: Object,
      
      // a factory function
      default: function() {
        return { name: "Mr. 007", email: "james@bond.io" };
      }
    },
    
    season: {
      validator: function(value) {
        
        return ["winter", "summer", "autumn", "spring"].includes(value);
      }
    },
    
    skills: {
      type: Array,
      validator: prop => prop.every(e => typeof e === "string")
    },
    
    phoneNumber: {
      validator: prop => phoneNumberValidator(prop)
    }
  }

Let's explore the different use-cases applied here...

Basic Validation

A simple example of how we can add a number type to a prop:

props: {
  luckyNumber: Number,
}

Did you notice the prop's name was a camel-cased?

Camel-Case => Kebab-Case

Vue Automatically translates any camel-cased prop into kebab-case when used in a template.

Here is how you would pass the data in the previous example of luckyNumber:


<game-of-life :lucky-number="7"></game-of-life>

And here is how you would use the prop in the child component's template


<template>
  <h1>{{ luckyNumber }}</h1>
</template>

Now, let's cover some of the basic validation types...

Basic Type Validation

Out of the box, Vue allows these native types:

  • String
  • Number
  • Boolean
  • Array
  • Object
  • Date
  • Function
  • Symbol

So you can do things like this...

<script>
export default {
  props: {
    name: String,
    luckyNumber: Number,
    isLucky: Boolean,
    luckyPlaces: Array,
    luck: Object,
    birthday: Date,
    luckCallback: Function,
    friendsPromise: Promise 
  }
};
</script>

In addition, you can create your own custom constructors!

Function Constructor Validation

I don't use often that validation pattern myself but it definitely can be handy in certain use-cases.

Here is a simple demonstration:

<script>
function Person(firstName, lastName) {
  this.firstName = firstName;
  this.lastName = lastName;
}

export default {
  props: {
    author: Person
  }
};
</script>

You may have also noticed earlier that there were some validator functions used in the props list. Let's have a closer look at these...

Validators

The validator property allows you to create your own custom validator function.

They are very handy for example when validating items of an array or object's values.

props: {
    
    season: {
      validator: function (value) {
        
        return ['winter', 'summer', 'autumn', 'spring'].includes(value)
      }
    },
    
    skills: {
      type: Array,
      validator: (prop) => prop.every(e => typeof e === 'string'),
    }
}

You can also have shared custom validation functions that you import to different components, here is an example of of a phone number validator...

props: {
  
  phoneNumber: {
    validator: prop => phoneNumberValidator(prop);
  }
}

export function phoneNumberValidator(data) {
  const phoneNumberRegex = /^[\+]?[(]?[0-9]{3}[)]?[-\s\.]?[0-9]{3}[-\s\.]?[0-9]{4,6}$/im;

  return data.match(phoneNumberRegex);
}

Default Prop Values

Vue allows you to define a default value for a prop.


props: {
  
  profile: {
    type: Object,
    
    // a factory function
    default: function () {
      return { name: 'Mr. 007', email: 'james@bond.io' }
    }
  },
  birthday: {
    type: Date,
    default: new Date('July 10, 1856'), 
  }
}

Note, for objects & arrays the default values must be returned through a function as you can see above.

When Validation Fails

If you happen to pass the wrong type to a prop, you should see in the console something similar to this...

Vue prop type validation error message example in the console.

Now you should know your way around props validations, time for some best-practices...

Best Practices 👌

Here are some guidelines I follow myself:

  • Always validate your props.
  • Always have a default value for non-required props.
  • Don't add a default value for required props.
  • Never mutate the prop, it may affect the parent's state in case of mutating objects & arrays.
  • Validator & default functions should be stateless since they run before the component is created.
  • Avoid declaring more than one type to a prop.

Resources

That is it, now you can validate your props like a pro! 🔥

Enjoyed the article? Share the summary thread on twitter.


View Original