Vue.js Events - Event Bus

If you're just getting started with this series of Vue.js posts, you should start with the Vue.js Starter Page.

You know all that stuff in the last post about the child broadcasting events up to the parent? That was a bunch of bullshit, turns out the REAL way to do all that stuff is with an Event Bus. Here's how:

Vue.js Events (using an Event Bus)

This file is actually a combination of 3 different files; Header.vue, Footer.vue and main.js.

Instead of worrying about the child/parent relationship and which way events and props should go, Vue.js can use something called an Event Bus which is nothing more than an additional Vue.js instance that can emit and listen for events all by its lonesome. Create the event bus file, then export it, and import it into whatever other Vue components you'll need to communicate with. Sorta' cuts out the parent as the middle man - I mean, do you really want to include your parents in all of your conversations with your siblings?

Line 5 is the simple creation of the Event Bus. The wheels on the bus go 'round and 'round.... Make sure to add the export modifier so that it's accessible by other components when needed.

In Header.vue on line 26 is the actual import statement that let's Header.vue reference the Event Bus. Once you have the reference it basically works the same as the previous example using the this.$emit. Instead of making a call to the local method you change it up to make a call to the bus instead bus.$emit(changeTitle,'My latest title');.

On line 95 the life cycle hook created() is used which, when called executes whatever is passed to it when the component is created. More life cycle events coming up in future posts.... And that flat arrow => is some ES6 b.s. that I'm working on....

<!--main.js-->
import Vue from 'vue'
import App from './App.vue'

export const bus = new Vue();

new Vue({
	el: '#app',
	render: h => h(app)
})

<-- end main.js-->

<!--Header.vue template-->
<!-- thanks to https://www.youtube.com/watch?v=6-us2D7GQCk&list=PL4cUxeGkcC9gQcYgjhBoeQH7wiAyZNrYa&index=21 -->

<template>
	<header>
		<h1 v-on:click="changeTitle">{{title}}</h1>
	</header>
</template>


<script>

	import {bus} from '..main';
	
	export default {
		props:{
			title:{
				type:String
			}
		},
		data(){
			return{
				title:'Vue Ninjas'
			}
		},
		methods(){
			changeTitle:function(){
				//this.$emit(changeTitle,'My latest title');
				bus.$emit(changeTitle,'My latest title');
			}
		}
	}
</script>

<!-- add "scoped" attribute to style tag to ensure that only elements in this component get style applied, else it goes global -->
<style scoped>

</style>


<!-- end Header.vue-->


<!-- start Footer.vue-->

<template>
  <div>
    <app-header v-bind:title="title" v-on:changeTitle="updateTitle($event)"></app-header>
	<app-muscles></app-muscles>
	<app-footer v-bind:title="title"></app-footer>
  </div>
</template>

<script>

	import Header from './components/Header.vue';
	import Footer from './components/Footer.vue';
	import Muscles from './components/Muscle.vue';

export default {
	  components{
		'app-header':Header;
		'app-footer':Footer;
		'app-muscles':Muscles;
	  },
  
  name: 'app',
  data () {
    return {
      muscles:[
			{name: 'Pectoralis', area:'Chest', show:false},
			{name: 'Biceps', area:'Arm', show:false},
			{name: 'Triceps', area:'Arm', show:false},
			{name: 'Latissimus', area:'Back', show:false},
			{name: 'Quadriceps', area:'Leg', show:false},
			{name: 'Soleus', area:'Calf', show:false}
		],
   		title:"Muscle Title Here"
    }
  },
  
  created(){
  	bus.$on('changeTitle',(data) => {
  	this.title = data;
  	})
  },
  
  methods:{
  	updateTitle(updatedTitle){
  		this.title=updatedTitle;
  	}
  }
}
</script>

<style>
	#app {
	  font-family: 'Avenir', Helvetica, Arial, sans-serif;
	  -webkit-font-smoothing: antialiased;
	  -moz-osx-font-smoothing: grayscale;
	  text-align: center;
	  color: #2c3e50;
	  margin-top: 60px;
	}

	h1, h2 {
	  font-weight: normal;
	}

	ul {
	  list-style-type: none;
	  padding: 0;
	}

	li {
	  display: inline-block;
	  margin: 0 10px;
	}

	a {
	  color: #42b983;
	}
	</style>

	<!-- end Footer.vue-->



Link your website to this page! Copy and paste the URL below:
http://www.cfsnap.com/vue-js/vue-js-events-event-bus/