Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to listen to all custom events in VueJS?

In my VueJS app I have a Vue instance which I'm using as an event bus for sending data between components.

It's just this:

import Vue from 'vue';
export const EventBus = new Vue();

Then in my components I import EventBus and use EventBus.$emit() and EventBus.$on().

This approach is explained here: https://alligator.io/vuejs/global-event-bus/

What I'd like to be able to do is listen to any event that is sent through EventBus. If I could bind one listener to all events I could use this for logging or to feed data into some system for my development environment that would show me all data as it went into eventBus, which would be super useful.

Is there any type of vm.$listenToEverything() that I'm missing or some way to make this work?

like image 252
JPollock Avatar asked May 12 '17 23:05

JPollock


People also ask

How do I listen to the Vue events?

Listening to Events We can use the v-on directive, which we typically shorten to the @ symbol, to listen to DOM events and run some JavaScript when they're triggered. The usage would be v-on:click="handler" or with the shortcut, @click="handler" .

What are custom events in Vue?

Vue takes an approach similar to the HTML DOM events. An element will "emit" an event and the data from that event. This is a robust way to handle custom events because we know that a child component has inputs (props) and outputs (custom events).

How do I watch data changes on Vue instance?

A Watcher in Vue. js is a special feature that allows one to watch a component and perform specified actions when the value of the component changes. It is a more generic way to observe and react to data changes in the Vue instance. Watchers are the most useful when used to perform asynchronous operations.

What does $emit do in Vue?

Vue $emit is a function that lets us emit, or send, custom events from a child component to its parent. In a standard Vue flow, it is the best way to trigger certain events.


1 Answers

If you're in an ES6 context, you could take either of below approaches. I explain through comments.

Override through inheritance

'use strict'

import Vue from 'vue'

export class EventBus extends Vue {
  // Register a custom callback as meddler that gets called upon each event emission.
  // It can be bound to $on as well. 
  $meddle (callback) {
    this.meddler = callback
  }

  // Override Vue's $emit to call the custom meddler callback upon each event emission.
  $emit (event, ...args) {
    if (this.meddler && typeof this.meddler.call === 'function') {
      this.meddler(event, ...args)
    }

    return super.$emit(event, ...args)
  }

  // We can also override $on() to listen to callbacks being registered.
}

export default new EventBus()

Override through hijacking

Or using a "hijacking" factory class in case you don't want your Vue event bus to be wrapped. The logic is basically the same, however, in this approach we hijack, or in other words, monkey patch the methods instead of overriding them directly.

'use strict'

import Vue from 'vue'

class EventBusFactory {
  static create () {
    return this.hijack(new Vue())
  }

  static hijack (bus) {
    bus.$meddle = callback => {
      bus.meddler = callback
    }

    const orig$emit = bus.$emit
    bus.$emit = (event, ...args) => {
      if (bus.meddler && typeof bus.meddler.call === 'function') {
        bus.meddler(event, ...args)
      }

      orig$emit.call(bus, event, ...args)
    }

    return bus
  }
}

export default EventBusFactory.create()
like image 151
sepehr Avatar answered Oct 24 '22 21:10

sepehr