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?
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" .
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).
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.
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.
If you're in an ES6 context, you could take either of below approaches. I explain through comments.
'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()
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()
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With