Initial experience of Vue's global event bus

Posted by Gayathri on Tue, 28 Dec 2021 10:17:14 +0100

Recently, I learned the global event bus from a silicon valley online course Vue, and wrote a blog to deepen my impression

Introduction to global event bus

EventBus is also called event bus. In Vue, you can use the concept of EventBus as a communication bridge, just like all components share the same event center. You can register with the center to send or receive events, so components can notify other components up and down in parallel, but it is too convenient. Therefore, if you use it carelessly, it will cause disasters that are difficult to maintain, Therefore, a more perfect Vuex is needed as the state management center to raise the concept of notification to the shared state level.

Relationship between vm object and component object

Prototype object of vm = = = prototype object of component object

Use of global event bus

User defined events in vue can complete the communication between child components and parent components, because the parent component can monitor the turntable in the child component, bind events for the child component, and trigger events in the parent component in the child component. Please understand the specific reasons My last blog

However, the communication between brother components is not good. The two components cannot see each other and cannot bind events to one another. So how do we solve it?

We can use an intermediary (tool man) to help us realize communication, and this intermediary component must be visible to both brother components, that is, the global event bus (all component objects can see). For example, if you want to ask Li Si for something, but you don't know others, then you need to find your common friend Zhang San as a bridge. The global event bus is a good man who knows everyone. Anyone can ask him to find another person to work.

First, a picture drawn by a big man

Conditions for becoming an event bus

  • All component objects must be able to see the bus object, so we put this object in the Vue prototype
  • The event bus object must be able to call on and emit methods (the bus object must be an instantiation object or a component object of Vue)

install

new Vue({
    ......
    beforeCreate() {
        Vue.prototype.$bus = this //Install the global event bus, $bus is the vm of the current application
    },
    ......
}) 

In main JS and put it in the beforeCreate() hook function

Use event bus

Receive data: if component a wants to receive data, bind a custom event to $bus in component A, and the callback of the event remains in component a itself.

realization A towards B signal communication

//A component: Call (distribute) events
       this.$bus.$emit('xxx',data)
//Component B: binding event listening
       this.$bus.$on('xxx',this.fn)


        methods{
            fn(data){

                }
            }

Provide data: this bus. Emit ('xxxx ', data)

Tips

It is better to use $off in the beforeDestroy hook to unbind the events used by the current component.

Small example (from a silicon valley online class)

File directory

App.vue

<template>
	<div class="app">
		<h1>{{msg}}</h1>
		<School/>
		<Student/>
	</div>
</template>

<script>
	import Student from './components/Student'
	import School from './components/School'

	export default {
		name:'App',
		components:{School,Student},
		data() {
			return {
				msg:'How do you do!',
			}
		}
	}
</script>

<style scoped>
	.app{
		background-color: gray;
		padding: 5px;
	}
</style>

School.vue

<template>
	<div class="school">
		<h2>School Name:{{name}}</h2>
		<h2>School address:{{address}}</h2>
	</div>
</template>

<script>
	export default {
		name:'School',
		data() {
			return {
				name:'Shang Silicon Valley',
				address:'Beijing',
			}
		},
		mounted() {
			// console.log('School',this)
			this.$bus.$on('hello',(data)=>{
				console.log('I am School Component, received data',data)
			})
		},
		beforeDestroy() {
			this.$bus.$off('hello')
		},
	}
</script>

<style scoped>
	.school{
		background-color: skyblue;
		padding: 5px;
	}
</style>

Student.vue

<template>
	<div class="student">
		<h2>Student Name:{{name}}</h2>
		<h2>Student gender:{{sex}}</h2>
		<button @click="sendStudentName">Give the students their names School assembly</button>
	</div>
</template>

<script>
	export default {
		name:'Student',
		data() {
			return {
				name:'Zhang San',
				sex:'male',
			}
		},
		mounted() {
			// console.log('Student',this.x)
		},
		methods: {
			sendStudentName(){
				this.$bus.$emit('hello',this.name)
			}
		},
	}
</script>

<style lang="less" scoped>
	.student{
		background-color: pink;
		padding: 5px;
		margin-top: 30px;
	}
</style>

main.js

//Introducing Vue
import Vue from "vue";
//Introduce App
import App from "./App.vue";
//Turn off Vue's production prompt
Vue.config.productionTip = false;

//Create vm
new Vue({
  el: "#app",
  render: (h) => h(App),
  beforeCreate() {
    Vue.prototype.$bus = this; //Installing the global event bus
  },
});

effect