|

Vue Sibling Component Communication

Vue Sibling Component Communication

Now we want to take a look at how Sibling Vue components can communicate with each other. We have already seen that a Parent can pass a prop to a child and a child can emit an event for communication. What about when a component wants to interact with a sibling component? There are a couple of ways to accomplish this and we’ll look at them now. One approach is to have the parent component act as the relay between two child components. The other option is to set up an event bus which allows direct communication between two child components with no need to involve the parent component.


Sibling Communication Through The Parent

The first method we’ll look at is for sibling to communicate with each other through a common parent component.


Sibling Component Communication Demo

We can start with a demonstration of sibling component communication in action. Note that we have an encompassing Parent component and two child components which are siblings. Go ahead and click the buttons on the sibling components to see how they communicate with each other.

Pretty cool right? Here are the Parent and Child Components that power the demo.


ParentCard.vue


SisterCard.vue


BrotherCard.vue


Sister To Parent To Brother Communication

So let’s see how this works. First we’ll look at how the sister communicates to the brother. This requires the Parent to act as an intermediary between the two sibling components.


1. SisterCard.vue

First off, in the <template> of the SisterCard.vue component, we set up a @click event listener for a messageBrother() function.


2. SisterCard.vue

Next up, the messageBrother() function in the <script> section of SisterCard.vue triggers. In this method, we emit a sistersaid event and pass a message of ‘Mom said do your homework!’ as the payload.


3. ParentCard.vue

Now in the <template>section of ParentCard.vue, we have a custom @sistersaid event listener which triggers a messageSon() function. So you see, the Parent is acting as a kind of relay between the two siblings here.


4. ParentCard.vue

In the <script> section of ParentCard.vue we now trigger the messageSon() function which accepts the payload from the custom event we had triggered just above and sets it to the messageson property.


5. ParentCard.vue

The messageson property in the <script> of ParentCard.vue was initially an empty string, but now contains the value ‘Mom said do your homework!’.


6. ParentCard.vue

This messageson property is bound to the <brother-card> (the sibling of <sister-card>) we are rendering in the <template> of ParentCard.vue.


7. BrotherCard.vue

In the <script> section of BrotherCard.vue, we are accepting the messageson property as a prop. We now have access to data that originated in SisterCard.vue and is now inside of BrotherCard.vue.


8. BrotherCard.vue

Lastly, in the <template> section of BrotherCard.vue we can make use of that data. We use a simple v-if to see if messageson has any useful data and if so, we display that message inside of an alert div. Cool!


Brother To Parent To Sister Communication

The process we described above also holds true going in reverse. Again, this requires the Parent to act as an intermediary between the two sibling components.


1. BrotherCard.vue

First off, in the <template> of the BrotherCard.vue component, we set up a @click event listener for a messageSister() function.


2. BrotherCard.vue

Next up, the messageSister() function in the <script> section of BrotherCard.vue triggers. In this method, we emit a brothersaid event and pass a message of ‘Mom said do your homework!’ as the payload.


3. ParentCard.vue

Now in the <template>section of ParentCard.vue, we have a custom @brothersaid event listener which triggers a messageDaughter() function. Once again, the Parent is acting as a kind of relay between the two siblings here.


4. ParentCard.vue

In the <script> section of ParentCard.vue we now trigger the messageDaughter() function which accepts the payload from the custom event we had triggered just above and sets it to the messagedaughter property.


5. ParentCard.vue

The messagedaughter property in the <script> of ParentCard.vue was initially an empty string, but now contains the value ‘Mom said do your homework!’.


6. ParentCard.vue

This messagedaughter property is bound to the <sister-card> (the sibling of <brother-card>) we are rendering in the <template> of ParentCard.vue.


7. BrotherCard.vue

In the <script> section of BrotherCard.vue, we are accepting the messagedaughter property as a prop. We now have access to data that originated in BrotherCard.vue and is now inside of SisterCard.vue.


8. BrotherCard.vue

Lastly, in the <template> section of BrotherCard.vue we can make use of that data. We use a simple v-if to see if messagedaughter has any useful data and if so, we display that message inside of an alert div. Cool!


Sibling Communication Via An Event Bus

As the application grows, passing everything through the parent component can become more tricky. Another option is to instead use an Event Bus type architecture for communicating between sibling components. This makes use of a central class or object to pass the data. Angular uses a similar architecture and it is called Services. Let’s see how we might make use of this.


Brother To Sister Communication

We can use this eventBus architecture to remove the Parent from the communication flow and allow sibling to sibling communication.


1. In the main.js file we can start by defining the new event bus class which is a Vue instance.
main.js


2. Now, we will import this new event bus into the BrotherCard.vue component.
BrotherCard.vue


3. The eventBus Vue instance will now be the one to emit an event in BrotherCard.vue. Notice this.$emit is now commented out, and eventBus.$emit is responsible. eventBus is just a Vue instance, and eventBus has this $emit method which is why we are able to do it this way. We still trigger the same custom event name and message.
BrotherCard.vue


4. Import the eventBus into the sibling SisterCard.vue file.
SisterCard.vue


5. Add the created() life cycle hook to SisterCard.vue. It is in the created() life cycle hook where we set up a listener for the custom event we just fired from the eventBus. This listener will begin and stay running when the SisterCard.vue component is rendered. The code below simply listens for the ‘brothersaid’ custom event, then triggers the shorthand notation callback you see assigning the message that was passed as the payload of the custom event to the ‘frombrother’ data property.
SisterCard.vue


6. Add the frombrother data property to the data() function in SisterCard.vue. We no longer use a prop from the Parent component in these child components. We are now talking directly between sibling components so we need to have a new data property which we will use to drive the template section.
SisterCard.vue


7. Now, in the <template> section of SisterCard.vue – we can conditionally display a message from the brother if there is one present.
SisterCard.vue


Brother To Sister Communication

Let’s set up the same thing in reverse so that the brother can also communicate to the sister.


1. Once again the main.js file has our eventBus definition which is exported as a constant.
main.js


2. The SisterCard.vue component imports the eventBus like we saw earlier.
SisterCard.vue


3. Again we emit a custom event using the eventBus itself in SisterCard.vue.
SisterCard.vue


4. The eventBus is imported into the BrotherCard.vue file.
BrotherCard.vue


5. The listener for the custom event is set up in the created() life cycle hook in BrotherCard.vue.
BrotherCard.vue


6. Add the fromsister data property to the data() function in BrotherCard.vue.
BrotherCard.vue


7. Now, in the <template> section of BrotherCard.vue – we can conditionally display a message from the sister if there is one present.
BrotherCard.vue


The Parent Component Is Now Simplified

In the parent component, all we have to do is render the children now. We no longer have any click handlers or event listeners in the parent, just a simple render of <brother-card></brother-card> and <sister-card></sister-card> like we see here.


Sibling To Sibling Communication Demo

Let’s check it out! The parent is completely out of the loop now. Those devious little kids!


Vue Sibling Component Communication Summary

In this tutorial we saw a couple of ways to handle communication between sibling components in VueJS. The first option had us communicating through the parent component using props and custom events. This is where the Parent acts as the relay between the two children. The second approach used an event bus where we were able to communicate directly between sibling components leaving Parent component out of the equation. This all comes down to managing state, and as you can see it can start to get a little tricky as your application grows. This is what the great VueX tool was created for. VueX simplifies state management and we’ll have a look at that tool in a future tutorial.

|