Vuejs - bubbling custom events Vuejs - bubbling custom events vue.js vue.js

Vuejs - bubbling custom events


There are 4 options I know of

  1. Re-emit events like you did
  2. Use this.$parent (repetitively) on the child component to access the desired parent and emit the event. (see "Implement your own bubbling event plugin" below)
  3. Use an event bus that is provided by the parent and injected in the children.
  4. Use a Vuex store and push events to an event queue in the child component. Somewhere else in the app, watch that reactive event queue for new elements or just bind it to something.

Implement your own bubbling event plugin

It's very simple. The plugin adds a new $bubble method that emits events that bubble to their parents. I considered publishing a plugin that does this, but it's so simple that the overhead is not worth it.

// Add this as a Vue pluginVue.use((Vue) => {  Vue.prototype.$bubble = function $bubble(eventName, ...args) {    // Emit the event on all parent components    let component = this;    do {      component.$emit(eventName, ...args);      component = component.$parent;    } while (component);  };});// Some nested components as an example// note usage of "$bubble" instead of "$emit"Vue.component('component-c', {  template: `    <button type="button" @click="$bubble('my-event', 'payload')">      Emit bubbling event    </button>`,});Vue.component('component-b', {  template: `<component-c @my-event="onMyEvent" />`,    methods: {    onMyEvent(...args) {      console.log('component-b listener: ', ...args);    },  },});Vue.component('component-a', {  template: `<component-b @my-event="onMyEvent" />`,    methods: {    onMyEvent(...args) {      console.log('component-a listener: ', ...args);    },  },});var vapp = new Vue({  el: '#app',  methods: {    onMyEvent(...args) {      console.log('root listener: ', ...args);    },  },});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script><div id="app">  <component-a @my-event="onMyEvent" /></div>