ORIGINAL LINK: https://www.digitalocean.com/community/tutorials/vuejs-global-event-bus
The event bus / publish-subscribe pattern, despite the bad press it sometimes gets, is still an excellent way of getting unrelated sections of your application to talk to each other. But wait! Before you go waste a few more precious KBs on another library, why not try Vue's powerful built-in event bus?
As it turns out, the event system used in Vue components is just as happy being used on its own.
Initializing
The first thing you'll need to do is create the event bus and export it somewhere so other modules and components can use it. Listen closely. This part might be tricky.
event-bus.js
import Vue from 'vue';
export const EventBus = new Vue();
What do you know? Turns out it wasn't tricky at all!
All you need to do is import the Vue library and export an instance of it. (In this case, I've called it EventBus
.) What you're essentially getting is a component that's entirely decoupled from the DOM or the rest of your app. All that exists on it are its instance methods, so it's pretty lightweight.
Using the Event Bus
Now that you've created the event bus, all you need to do to use it is import it in your components and call the same methods that you would use if you were passing messages between parent and child components.
Sending Events
Say you have a really excited component that feels the need to notify your entire app of how many times it has been clicked whenever someone clicks on it. Here's how you would go about implementing that using EventBus.emit(channel: string, payload1: any, …)
.
I'm using a single-file-component here, but you can use whatever method of creating components you'd like.
PleaseClickMe.vue<template> <div class="pleeease-click-me" @click="emitGlobalClickEvent()"></div> </template> <script> // Import the EventBus we just created. import { EventBus } from './event-bus.js'; export default { data() { return { clickCount: 0 } }, methods: { emitGlobalClickEvent() { this.clickCount++; // Send the event on a channel (i-got-clicked) with a payload (the click count.) EventBus.$emit('i-got-clicked', this.clickCount); } } } </script>
Receiving Events
Now, any other part of your app kind enough to give
PleaseClickMe.vue
the attention it so desperately craves can importEventBus
and listen on thei-got-clicked
channel usingEventBus.$on(channel: string, callback(payload1,…))
.the-kindly-script.js // Import the EventBus. import { EventBus } from './event-bus.js'; // Listen for the i-got-clicked event and its payload. EventBus.$on('i-got-clicked', clickCount => { console.log(`Oh, that's nice. It's gotten ${clickCount} clicks! :)`) });
- If you'd only like to listen for the first emission of an event, you can use
EventBus.$once(channel: string, callback(payload1,…))
.
Removing Event Listeners
Once a part of your app gets tired of hearing the amount of times PleaseClickMe.vue
has been clicked, they can unregister their handler from that channel like so.
// Import the EventBus we just created.
import { EventBus } from './event-bus.js';
// The event handler function.
const clickHandler = function(clickCount) {
console.log(`Oh, that's nice. It's gotten ${clickCount} clicks! :)`)
}
// Listen to the event.
EventBus.$on('i-got-clicked', clickHandler);
// Stop listening.
EventBus.$off('i-got-clicked', clickHandler);
You could also remove all listeners for a particular event using EventBus.$off('i-got-clicked')
with no callback argument.
If you really need to remove every single listener from EventBus
, regardless of channel, you can call EventBus.$off()
with no arguments at all.
👉 Now go forth and be eventful!
0 comment