Skip to content

Communication between sibling components in Vue.js 2.0

Overview

In Vue.js 2.x, model.sync will be deprecated.

So, what is a proper way to communicate between sibling components in Vue.js 2.x?


Background

As I understand Vue.js 2.x, the preferred method for sibling communication is to use a store or an event bus.

According to Evan (creator of Vue.js):

It’s also worth mentioning “passing data between components” is generally a bad idea, because in the end the data flow becomes untrackable and very hard to debug.

If a piece of data needs to be shared by multiple components, prefer global stores or Vuex.

[Link to discussion]

And:

.once and .sync are deprecated. Props are now always one-way down. To produce side effects in the parent scope, a component needs to explicitly emit an event instead of relying on implicit binding.

So, Evan suggests using $emit() and $on().


Concerns

What worries me is:

  • Each store and event has a global visibility (correct me if I’m wrong);
  • It’s too wasteful to create a new store for each minor communication;

What I want is to some scope events or stores visibility for siblings components. (Or perhaps I didn’t understand the above idea.)


Question

So, what is the correct way to communicate between sibling components?

Answer

With Vue.js 2.0, I’m using the eventHub mechanism as demonstrated in the documentation.

  1. Define centralized event hub.

     const eventHub = new Vue() // Single event hub
    
     // Distribute to components using global mixin
     Vue.mixin({
         data: function () {
             return {
                 eventHub: eventHub
             }
         }
     })
    
  2. Now in your component you can emit events with

     this.eventHub.$emit('update', data)
    
  3. And to listen you do

     this.eventHub.$on('update', data => {
     // do your thing
     })
    

Update

Please see the answer by alex, which describes a simpler solution.