JSFiddle - React, Tailwind, and code Playground
by simati
HTML
<div id="app">
<listens-for-event></listens-for-event>
<fires-event></fires-event>
</div>
JavaScript
/*
* By extending the Vue prototype with a new '$bus' property
* we can easily access our global event bus from any child component.
*/
Object.defineProperty(Vue.prototype, '$bus', {
get() {
return this.$root.bus;
}
});
/*
* The first component we register will listen for an event
* to be fired by our global event bus.
*/
Vue.component('listens-for-event', {
template: `<div>{{ msg }}</div>`,
ready() {
// Register event listener
this.$bus.$on('specialEvent', (event) => {
this.msg = event.msg;
alert(event.alert);
console.log(event);
});
},
data() {
return {
msg: 'I am listening for an event.'
}
}
});
/*
* This next component will the component firing the event.
*
* Note: In this example, there's one component firing an event
* and one component listening for an event. In reality,
* any component is free to both fire & listen for events.
*/
Vue.component('fires-event', {
template: `<div>{{ msg }}</div>`,
ready() {
// We're using setTimeout() to spoof an async call.
setTimeout(() => {
// emit the event and pass with it an object of "event data".
this.$bus.$emit('specialEvent', {
msg: 'This message came from the event.',
alert: 'Alert! Alert! Alert!'
});
this.msg = 'I fired an event.'
}, 2500);
},
data() {
return {
msg: 'I am getting ready to fire an event.'
}
}
});
var bus = new Vue({}) // This empty Vue model will serve as our event bus.
// Let's define out $root Vue model now.
new Vue({
el: '#app',
data: {
bus: bus // Here we bind our event bus to our $root Vue model.
}
});