Overcoming race conditions when using a global event bus in Vue.js

To ease communication between components which are not directly related, and when using a state manager such as Vuex seems overkill, Vue.js developers' go-to pattern is the global event bus: while it feels kind of hacky, it most certainly is easy to both use and reason about.

Or is it though? Depending on your specific use case, there is virtually no guarantee the event listeners will be bound before the events are emitted. Wouldn't it be nice if we had some sort of mechanism that could keep the early-emitted values in memory and apply them upon binding the listeners? Why do I keep asking questions when you know damn well the answer lies right below?

import Vue from "vue";

const bus = new Vue();
const lastValues = {};
const originalEmit = bus.$emit.bind(bus);
const originalOn = bus.$on.bind(bus);

bus.$emit = function(name, value) {
lastValues[name] = value;
originalEmit(name, value);

bus.$on = function(name, callback) {
if (lastValues[name] !== undefined) {

originalOn(name, callback);

export default bus;

This is, too, sort of hacky, but it most certainly does the trick, remains lighter than Vuex, and is conceptually not too far away from immediately-applied watchers one can define in their components. Let me know your thoughts!