How to communicate between Vue.js components?

When you're building a Vue.js app you are going to need to communicate between your components. In this lesson, we are going to go over how we can pass data from a parent component to a child and how to pass data back again.


Passing data to a child component

Passing variable to a child component is probably the most common way to communicate with a component. First I'm going to show an example of how to pass a static value to a child component.

Vue Hero - Passing data to a child component

Here we have created a component called "invoice-item". This component accepts one property called "quantity". We have defined in the list of props that "quantity" should be a Number. Try to be as specific as possible when you are setting which props that should be allowed. It is possible to just use "props: ['quantity']", but that is not best practice and the component would have no clue which type of data is being passed to it.

See the Pen How to communicate between components - 1 by Vue Hero (@vuehero) on CodePen.

If we wanted the quantity value to be dynamic we could bind a value to it using v-bind. Like this:

Vue Hero - Passing data to a child component 2

Here is a couple of other ways to pass data to a child component:

Vue Hero - Passing data to a child component 3

The props that are passed down to a component are immutable. So you should never try to change a property inside the component. Change it in the parent component instead and it will automatically be updated in side the child component because of Vue's reactivity system.

Passing data back to it's parent component

Let's say that we have a component which contain a form. In this case, it's often necessary to pass data back to the parent component. This can be done in multiple ways. Here is an example of how to do this by using $emit.

Vue Hero - Passing data to a child component 4

What we have done here is that we first inserted the component in the template and passed in the quantity, just like earlier. We added an event listener (@increase is the same as v-on:increase) which calls increaseQuantity when it's being called.
Inside the component we created we accept the quantity as a property and inside the template, we added a @click listener which calls the increase method inside our child component. Inside the increase method, we call $emit which passes information back up to its parent.

See the Pen How to communicate between components - 2 by Vue Hero (@vuehero) on CodePen.

It would probably make more sense to just increase the quantity by one when increaseQuantity is being called, but we pass 1 as a variable so that you can see how it works.

Pass data using an event bus

There is actually one more way to pass data between components and that is done using something called an event bus. By using event buses we are no longer limited to just child<->parent communication. Using an event bus is very similar to using the $emit. The main difference is that you add the listener when you mount the component instead of adding the listener to the component itself. Here is an example:

Vue Hero - Passing data to a child component 5

Here you see that in the parent component (Invoice) we added a listener on the root when the component is being mounted. This event listener can be added to all other components in the app because of the event bus that is being used on the $root element.

Summary

Now that we have gone over how you can communicate between components I hope you understood enough so that you could start using this knowledge in your own projects.