Vue.js How to deal with deprecation of $dispatch and $broadcast? (bus event pattern)


Example

You might have realized that $emit is scoped to the component that is emitting the event. That's a problem when you want to communicate between components far from one another in the component tree.

Note: In Vue1 you coud use $dispatch or $broadcast, but not in Vue2. The reason being that it doesn't scale well. There is a popular bus pattern to manage this:

DEMO

HTML

<script type="x-template" id="sender">
  <button @click="bus.$emit('new-event')">Click me to send an event !</button>
</script>
 
<script type="x-template" id="receiver">
  <div>I received {{numberOfEvents}} event{{numberOfEvents == 1 ? '' : 's'}}</div>
</script>
 
<sender></sender>
<receiver></receiver>

JS

var bus = new Vue();
 
var senderComponent = {
  template: '#sender',
  data() {
    return {
      bus: bus
    }
  }
};
 
var receiverComponent = {
  template: '#receiver',
  data() {
    return {
      numberOfEvents: 0
    }
  },
  ready() {
    var self = this;
 
    bus.$on('new-event', function() {
      ++self.numberOfEvents;
    });
  }
};
 
new Vue({
  el: 'body',
  components: {
    'sender': senderComponent,
    'receiver': receiverComponent
  }
});

You just need to understand that any Vue() instance can $emit and catch ($on) an event. We just declare a global Vue instance call bus and then any component with this variable can emit and catch events from it. Just make sure the component has access to the bus variable.