We have implemented everything that we have learned so far, from navigation and API services to data display. It’s time to dive deeper into more complicated things which we are going to make easy to understand.

We are going to make an additional component and then show how communication between parent-child components works.

For the complete series navigation visit: Vue.js Series.

To download the source code for this part, visit Components Props and Events.

This post is divided into several sections:

Creating a New Component

Do you remember the OwnerList component from a previous part? We are going to make a new component which will render a data of single owner inside <tr> tag for the OwnerList’s table.

Let’s navigate to src/components/owner and create the OwnerListRow.vue component:

In the example above we have used the owner variable but where did we declare it? The owner variable is located in the props array and that means that our new component expects from a parent component to send the owner object to this component as a property. So, what we need to do is to declare this OwnerListRow component in the OwnerList component, render it instead of the old <tr> tag and then send the owner object back to the OwnerListRow component.

We are going to do exactly that:

Let’s analyze this code. First, we import the new OwnerListRow component. Then, we inform Vue.js that we want to use the OwnerListRow inside of this component. We do that by specifying a component’s name inside the components JSON object. Right now, Vue.js is going to create a custom tag owner-list-row that will point to the OwnerListRow component under the hood. Otherwise, we can specify a custom tag as well by changing it to:

But we are satisfied with the auto-generated name and we will continue to use it.

Now when we have the custom tag for our component, we are going to replace the <tr> tag with it. Let’s examine the following code snippet:

In this code, we have the v-for directive and the :key prop, that help us render our owner-list-row component for every owner in the owners array. But also, in every iteration, we pass that owner to the child component by using the :owner="owner" statement. That’s called data binding and we have two type of data bindings. In this example, we use a colon (:) and it stands for dynamic binding. Its purpose is to bind variables, in this case, the owner object with all of its properties. If we change our owner in any way, child component will be notified about it and will receive a new value. That’s called reactivity.

Another type of binding is without the colon and that type of binding only binds a string. For example, if we write owner=”owner” then we only pass the string owner and not the actual variable owner.

Let’s open a terminal and type npm run dev to analyze results:
Owner List Table - Props and Events

As we can see, everything works the same as it worked in the previous part. We did this because it’s a good practice to have smaller components that we can reuse in other components.

Our next task is to show all the details for a single owner. For now, we are going to show owner details when we click on the table row. To do that, we need to listen to the click event of that <tr> tag.

Event Handling

Vue.js can listen to native javascript events like onclick, onmouseover, etc. We can make our own events as well and listen to them. So, what we are going to do is to show you the usage of both cases right now.

Let’s modify the template of the OwnerList.vue component:

Also, let’s create onOwnerClicked method inside a script tag:

We can listen to events with @nameOfEvent and that event can reside in the native HTML tags as well as in the custom components. But there is some difference.

If an event listener is placed on native HTML tags, then we are listening to the native JavaScript events. For example, if we write: <div @click=”clickHandler”/> we will listen to onClick event and will call the clickHandler from the method’s object in the script tag. But if we want to listen on native JavaScript events on custom components, we need to use the .native modifier to tell Vue.js to listen on native events and not on custom events.

We will show how to use the custom events in a few moments.

When we click on the first row, onOwnerClicked method is triggered and we got the id of that owner in the console:
On Owner Clicked Event - Props and Events

Great.

We want to emit custom events for every button in our OwnerListRow.vue component.

Let’s do exactly that:

You may wonder how can we listen to the click event on the b-button element. That’s because the b-button element emits a custom event named click when we click on that button. That’s exactly what we will use here. We’ll listen for the click event on all three buttons and then we’ll emit new events named details, update and delete. We also pass the owner’s id as a parameter of that event.

Great!

Now let’s listen to those events in the OwnerList.vue component. We are going to delete the @click.native event listener because we are going to open owner’s details when we click on the details button and not on a table row.

Let’s open a web browser and click on all of the buttons to inspect results:
All Three Events are Working - Props and Events

Everything seems to be working!

Conclusion

Excellent. You have learned how to bind and pass some data to child components and also how to notify parent component about some events.

By reading this post you’ve learned:

  • The way of creating component props
  • How data binding works in Vue.js
  • How to listen to events
  • And how to create custom events

In the next part of this series, we are going to use the id parameter to display the details about a single owner, as well as update it and delete it.