Vue JS — Props Validator

I recently started to work on vue js and I came across the custom validation for the props in components. To give a brief about props, you can pass data to child component with the help of props. For example ,
Vue.component('blog-post',{
props: ['title'],
template: '<h3>{{ title }}</h3>'
})
Above code snippet is a component ‘blog-post’ takes property ‘title’ and renders it in the template. You can pass data to this component
<blog-post title="My journey with Vue"></blog-post>
Note: A component can have any number of props. For example
props: ['title', 'likes', 'isPublished', 'commentIds', 'author']
Now that we know that we can have more props but we are not sure what data they can hold, to make them more descriptive we can have the below properties
- type
- required
- default
- validator
props:
{
title: String,
likes: Number,
isPublished: Boolean,
commentIds: Array,
author: Object
}
In the above example, we can see that the properties name and their type are defined. This gives us more clarity on what data type the props holds.
By default, props are optional, but you can make them mandatory by adding required and also it is advised to have default value for required props to handle fail over case.
props: {
title: {
type: String,
required: true,
default: '' // if component fails to receive the property. '' will be passed as default value
},
likes: {
type: Number,
default: 0 // if component fails to receive the property. 0 will be passed as default value
}
}
Note, if you specify default value to a property, it automatically means its required:true
We can further add validation to our property, to make sure that, you props get the right data
props: {likes: {
type: Number,
default: 0,
validator: function (inputValue) {
return inputValue >= 0&& inputValue <= 100
}
}
This validator will now check whether the number is between 0 to 100, if not it will give false which will make the validator to fail. By this we can add validations to our props too.
That was an easy validation, lets see how can we validate an Array.
Lets assume we have a property called cars which will takes array of objects (car), we need to validate that every car object passed has color and brand_name as attributes,
cars: {type: Array,required: true,validator (cars) {if (!(cars&& cars.constructor === Array)) return falseconst mandatoryProperties= ['brand_name','color']let result = truecars.forEach(item => {const keys = Object.keys(item)if (!mandatoryProperties.every(e => keys.includes(e))) {result = false}})return result
}
}
In above code, we check that every car object holds brand_name and color attributes in them. By this we can be more sure that our car that we will be rendering in html will have these mandatory values.
How about some unit test for the above code, I use Jest for unit testing my vue components, here you find the unit test for the above code snippet
describe('Component with props validation', () => {
it('validate props cars', () => {
// mount your cars component
expect(shallowMount(carsComponent)).vm.$options.props.cars.validator({})).toBe(false) // validator will fail as its not of type Array// pass cars with mandatory attributesexpect(shallowMount(carsComponent)).vm.$options.props.cars.validator([{
'brand_name': 'Benz',
'color': 'black'
}])).toBe(true) // validator will pass as its has all attributesexpect(shallowMount(carsComponent)).vm.$options.props.cars.validator([{
'brand_name': 'Benz'
}])).toBe(false) // no color attribute })
})
By this, You can be more sure about the props you define in a component.
Happy Coding!!