Global Bus v Page Bus ?



  • I’ve been using the global event bus to create decoupled components for a PWA.

    It works great until there are multiple instances of a page in the browsing history - each instance continues to receive and process events.

    Options

    1. Ignore it - just make sure event handlers are lightweight and idempotent.

    2. Introduce scope into the global bus (e.g. override $emit and $listen to prefix events with id of root component).

    3. Create a “page-bus” for each instance.

    4. Do something else.

    Any else had experience of this?



  • @rab

    For anyone interested this works as a plugin solution. Please shout if you have a better approach or can contribute to improving this one; e.g.:

    1. Locating the page root is an educated guess and may not fit all cases.
    2. Desirable to use this.$page.$emit rather than this.$$emit.
    3. A better solution using Vue extends may exist.
    /* pagebus.js
    
    Using the global event bus to decouple components in a PWA works great
    until there are multiple copies of a page instance in the browsing history;
    each instance continues to receive and respond to events - especially
    troublesome when one of the components fetches data from the server
    (the data is fetched multiple times).
    
    An interim workaround is provided here by propagating events and listeners 
    to the 'page' root not the 'app' root.
    
    TO DO:
    
      1. Locating the page root is an educated guess and may not fit all cases.
      2. Desirable to use this.$page.$emit rather than this.$$emit.
      3. A better solution using Vue extends may exist.
    
    */
    
    import Vue from 'vue'
    
    const DEBUG = true
    
    export default {
      install (Vue, options) {
        Vue.mixin({
          methods: {
            $$page: function () {
              // find the page root (educated guess)
              let x = this;
              do {
                x = x.$parent;
              } while (x && x.$parent && x.$parent.$parent !== x.$root);
              return x
            },
            $$on: function (ev, ...args) {
              // propagate to page root component
              DEBUG && console.log('-> pagebus: on', this._uid, ev, args)
              return (this.$$page() || this).$on(ev, ...args)
            },
            $$emit: function (ev, ...args) {
              // propagate to page root component
              DEBUG && console.log('-> pagebus: emit', this._uid, ev, args)
              return (this.$$page() || this).$emit(ev, ...args)
            }
          }
        })
      }
    }
    

Log in to reply