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.
	}
});