Components are meant to be reusable. And even though we used multiple instances of our click counter component, it's quite hard to understand the benefits of reusability without seeing a more realistic example. That's what we'll do in this lesson. I have here some markup that renders a page for a coffee subscription service.
It has some headings and a list of available plans. All these divs have the exact same markup, and their purpose is to display a single plan. If we had a component here, like Plan, then we would be able to type something like this. This reduces the amount of markup, while it makes the code more understandable at first glance.
OK, we can actually make that work. js file by creating the component that I will name Plan. Just so you know, single word component names like Plan or To Do are considered a bad practice. They should be avoided because they might collide with existing or future HTML elements.
I will stick to Plan for now though for simplicity's sake and will cover the best practices on component names in a later lesson. Let's say that the template for this component will be the one with the ID of Plan template. which we can go create now. Remember the syntax here.
It's a script tag with the type of text slash x template and we'll need to give it that ID of plan template. Now in this template, I'll put one of the divs from the code above with the class of plan. If I refresh the page now, we get one more plan in the list. It doesn't show the name.
We specified here, but that makes sense. We've hard coded a plan in the template that's called the curious. So what we need to do here is somehow make it possible for the component to receive this name. Well, to use this syntax, we'd actually need to use slots and we'll cover that later in this course.
For now though, let's pass the name to our component like this. This is called a prop. Props are custom attributes that you can register on a component. In order to then use a prop, you have to define it in the list of props that the component accepts.
Using the props option, we can name our props almost anything we'd like. In our case, we want a name for our plan. Cool. Now we can access the values of props just as if they were data properties.
So in the template, We can use mustache syntax name. If we refresh the page now, sure enough, we get the new plan that has the name that we passed. That's great. Let's do the same for the other plans.
We can move all this verbose markup for each one and replace them with instances of our plan component. If we refresh the page now, sweet. We have the same output as the one we began with, but Look how much shorter and more readable our markup is. We had about 20 lines of code or so, and now we only have three.
Another thing that we could do here is to create an array with the planned names in the root component instance. Then we could pass them dynamically to the components instead of hard coding the planned names in the markup. We can do that using the v4 directive. as we would for any other HTML element.
Thus, to create multiple plans, we will iterate over each plan in our plans array. Then we have to pass the corresponding name to each plan. If we pass it in like this, then the word plan would be the actual name. Let me show you that real quick in the browser.
Yeah, it's just the plan word printed out here. This is because we've passed it as a string. As you're probably thinking, we have to use vbind in order to bind the name attribute to the value of the plan. If we refresh the page now, we get all the plans correctly again.
Awesome. How smooth is that? I'll go ahead and remove the extra plans now from the markup. Before we move on to the next topic, let me show you one more thing.
The props option. can be an array, as we have it here. But this way, we don't have all that much control. Another way to define props is by using an object instead.
Here, the keys are the names of the props. Then the value can be the type of the prop. For the name, the type will be a string. If we had another prop, like the price of the plan, then that could be a number.
This syntax helps you to document your component and will also throw a warning in the browser's console if you pass a value incorrectly. Let's see what happens if we pass a boolean value to the name prop. We can see in the console that view is complaining. It says invalid prop, type check failed for prop name, expected string and got boolean with value of true.
That's pretty cool. and very specific, thus making it super helpful. Going even further though, we could even make the value of the property an object that has the key of type and goes on to unlock a number of other options to pass here. For example, we could also set a default value or we can make the prop required and even create custom validation rules.
While you don't necessarily need to know all these things right this moment, I just wanted to give you a little idea of what was possible. I'll remove the unneeded default option for now, as well as the unneeded price prop. Alright, let's review what we have done so far. First, we created a component that uses the plan template and accepts a name prop.
The template itself is the markup that creates the plan. in which the value of the name property is printed. In our application, we create multiple instances of the plan component for each of the plans that we have defined in the data, and we pass the plan to the name prop. Components are meant to be reusable.
And even though we used multiple instances of our click counter component, it's quite hard to understand the benefits of reusability without seeing a more realistic example. That's what we'll do in this lesson. I have here some markup that renders a page for a coffee subscription service. It has some headings and a list of available plans.
All these divs have the exact same markup, and their purpose is to display a single plan. If we had a component here, like Plan, then we would be able to type something like this. This reduces the amount of markup, while it makes the code more understandable at first glance. OK, we can actually make that work.
js file by creating the component that I will name Plan. Just so you know, single word component names like Plan or To Do are considered a bad practice. They should be avoided because they might collide with existing or future HTML elements. I will stick to Plan for now though for simplicity's sake and will cover the best practices on component names in a later lesson.
Let's say that the template for this component will be the one with the ID of Plan template. which we can go create now. Remember the syntax here. It's a script tag with the type of text slash x template and we'll need to give it that ID of plan template.
Now in this template, I'll put one of the divs from the code above with the class of plan. If I refresh the page now, we get one more plan in the list. It doesn't show the name. We specified here, but that makes sense.
We've hard coded a plan in the template that's called the curious. So what we need to do here is somehow make it possible for the component to receive this name. Well, to use this syntax, we'd actually need to use slots and we'll cover that later in this course. For now though, let's pass the name to our component like this.
This is called a prop. Props are custom attributes that you can register on a component. In order to then use a prop, you have to define it in the list of props that the component accepts. Using the props option, we can name our props almost anything we'd like.
In our case, we want a name for our plan. Cool. Now we can access the values of props just as if they were data properties. So in the template, We can use mustache syntax name.
If we refresh the page now, sure enough, we get the new plan that has the name that we passed. That's great. Let's do the same for the other plans. We can move all this verbose markup for each one and replace them with instances of our plan component.
If we refresh the page now, sweet. We have the same output as the one we began with, but Look how much shorter and more readable our markup is. We had about 20 lines of code or so, and now we only have three. Another thing that we could do here is to create an array with the planned names in the root component instance.
Then we could pass them dynamically to the components instead of hard coding the planned names in the markup. We can do that using the v4 directive. as we would for any other HTML element. Thus, to create multiple plans, we will iterate over each plan in our plans array.
Then we have to pass the corresponding name to each plan. If we pass it in like this, then the word plan would be the actual name. Let me show you that real quick in the browser. Yeah, it's just the plan word printed out here.
This is because we've passed it as a string. As you're probably thinking, we have to use vbind in order to bind the name attribute to the value of the plan. If we refresh the page now, we get all the plans correctly again. Awesome.
How smooth is that? I'll go ahead and remove the extra plans now from the markup. Before we move on to the next topic, let me show you one more thing. The props option.
can be an array, as we have it here. But this way, we don't have all that much control. Another way to define props is by using an object instead. Here, the keys are the names of the props.
Then the value can be the type of the prop. For the name, the type will be a string. If we had another prop, like the price of the plan, then that could be a number. This syntax helps you to document your component and will also throw a warning in the browser's console if you pass a value incorrectly.
Let's see what happens if we pass a boolean value to the name prop. We can see in the console that view is complaining. It says invalid prop, type check failed for prop name, expected string and got boolean with value of true. That's pretty cool.
and very specific, thus making it super helpful. Going even further though, we could even make the value of the property an object that has the key of type and goes on to unlock a number of other options to pass here. For example, we could also set a default value or we can make the prop required and even create custom validation rules. While you don't necessarily need to know all these things right this moment, I just wanted to give you a little idea of what was possible.
I'll remove the unneeded default option for now, as well as the unneeded price prop. Alright, let's review what we have done so far. First, we created a component that uses the plan template and accepts a name prop. The template itself is the markup that creates the plan.
in which the value of the name property is printed. In our application, we create multiple instances of the plan component for each of the plans that we have defined in the data, and we pass the plan to the name prop.