Validating Props in Vue
Validating Props in Vue

In this video I want to talk deeper about validating component props in Vue

In one of the previous videos we already used props to define what params we need to pass inside our component. We did it in UsersList component.
As it's a really awesome feature which helps you to build safer application we need to learn about it a bit deeper.
Let's say that we want to create a sharable pagination component. We won't create it for real but I want to strictly define what parameters to need to pass inside.

First we need to add our sharable component.

<template>
  <div>Pagination</div>
</template>

<script>
export default {
  name: "Pagination",
};
</script>

Now let's use it somewhere so that we can check how it works.

import Pagination from "@/components/Pagination";

export default {
  name: "Users",
  components: { UsersList, Pagination }
  ...
}

Now let's render it inside template.

<pagination />

As you can see our new sharable component is successfully rendered. Now let's think what do we need to provide from outside so our pagination component has enough information to work with. First of all it's total amount of elements. Normally we get this information from the backend in API request. And our pagination component for sure can't work without this information.

Let's add new prop for total.

export default {
  name: "Pagination",
  props: {
    total: {
      type: Number,
      required: true,
    },
  },
};

As you can see I wrote that it should be of a type number and it is required. Let's check in browser now. You can see that we are getting a nice and clear message that we didn't provide total inside a component. And this really simplifies usage of components especially if you can lots of parameters.
It's also possible to just write a type in prop and not an object. I recommend you to always write full notation because the you explicitly set if your prop is required or not.

Let's fix the error and provide a value from outside.

<pagination :total="total" />
data() {
  return {
    ...
    total: 500,
  };
},

As you can see no error this time. And what is really awesome you have this checks in runtime. So if you try to pass there string and not a number then you will get an error in console. Which is actually better for me then in Typescript world where the value outside has a type Number but in reality it's a string and your code is broken because it won't work in runtime.

The next prop that we want to specify is limit. It's how many items do we have per page.

Pagination.vue

limit: {
  type: Number,
  required: true,
},

Users.vue

<pagination :total="total" :limit="limit" />
data() {
  return {
    users: [],
    total: 500,
    limit: 20,
  };
},

Same as previously to avoid the error we need to specify it outside. The next one is currentPage. We want for sure to know what page is active now to highlight it.

Pagination.vue

currentPage: {
  type: Number,
  required: true,
},

Users.vue

<pagination :total="total" :limit="limit" :currentPage="currentPage" />
data() {
  return {
    users: [],
    total: 500,
    limit: 20,
    currentPage: 5,
  };
},

And the last is the url. We need to provide the base url where we are so that each element in pagination can have a correct user. So normally we will use this url inside and attach to it page=number in the loop.

Pagination.vue

url: {
  type: String,
  required: true,
},

Users.vue

<pagination
  :total="total"
  :limit="limit"
  :currentPage="currentPage"
  :url="url"
/>

```javascript
data() {
  return {
    users: [],
    total: 500,
    limit: 20,
    currentPage: 5,
    url: "/tags/dragons",
  };
},

As you can see our component is fully covered with props. We didn't need to specify a lot but now it's super clear what prop are needed and required and we will get an error it the prop is missing or the type is not correct.

One more thing which is really useful inside the props is default value. So we can provide a default which will be used if the value is not there. Let's say that limit is not mandatory and should be 10 by default.

limit: {
  type: Number,
  default: 10,
},

In this case limit is not mandatory and if we don't provide a value it will be 10 by default.

It's also possible to write custom validators for props if you need to but in my experience I needed it only once and normally just covered all components with default validators.

It's super important to define props for component correctly because it will save you later debugging time when you wrote that some property is not required or didn't specify the correct type.

If "Vue for beginners" is too easy for you go check my advanced course about Vue which is going 10 course and where we are creating together the application from empty folder to fully finished application.

📚 Source code of what we've done