Vue.js – global event bus

Vue is very nice JavaScript framework – fast to use and with clean code. Most of rules are logical and easy to understand, but some limitations may be strange and problematic. One of them is one-way data flow. We can pass data from parents to child elements automatically, but in reverse, use only events data. Sometimes it may be an issue, because we have nested components structure and would like to send event to top level parent.

First solution for that is to emit event from child to parent, and then… also emit event, but to higher level parent etc, so use all according to official documentation. See a simplified example of this implementation:

/* GrandchildComponent */
grandChildMethod () {
	this.$emit('grandChildEvent', optionalData)
}


/* ChildComponent */
<grandchild
	v-on:grandChildEvent="makeChildEvent"
></grandchild>
(...)
makeChildEvent (optionalData) {
	this.$emit('childEvent', optionalData)
}


/* ParentComponent */
<child
	v-on:childEvent="doSomething"
></child>
(...)
doSomething (optionalData) {
	// Do something, finally!
}

It works fine and it’s good option, but if we have several similar parts of code, it will real mess and we definitely don’t want to do this. So, what can we do? The solution is to use global event bus. We can declarare it on one place, and then use on every component, without need to use some components only to resend events between others. We need to create new file only for event bus and then import it on components. It’s very simple, there is an example of eventBus.js:

import Vue from 'vue'
export const proposalEventBus = new Vue()

And then we can use it on components, for example in nestedChild.vue:

import { globalEventBus } from './globalEventBus
(...)
myMethod () {
    globalEventBus.$emit('someEvent', optionalData)
}

Then react to this in for example topLevelParent.vue, add event listener on for example beforeMount function:

import { globalEventBus } from '../mixins/globalEventBus’
beforeMount: function () {
   globalEventBus.$on('someEvent', this.myCustomMethod)
}

As you can see, we created main event bus in separate file and just import it in every needed component. If you want or need, you can create many event buses in the same way. There are no limitations to this, and it be good option in very complicated app with a lot of components with events.