Vue2--Vue脚手架全局事件总线

507 阅读1分钟

全局事件总线介绍

1、作用:一种组件之间通信的方式,适用于任意组件之间通信,原理图如下:

image.png

2、对上图中x的要求:

(1)保证所有组件都能看到x

(2)能调用到 $on()$off()$emit() 方法

3、分析如何设置全局事件总线:首先要满足以上两点要求,可以借助Vue原型对象来实现,因为VueComponent.prototype.__proto__ === Vue.prototype这个重要的内置关系。如果我们在Vue原型上添加总线,那么所有组件都能访问到这个总线。也就是说我们要将组件加在下图中红色框框里。

image.png

4、使用全局事件总线的步骤:

这里我们不用x表示全局事件总线,用$bus来表示全局事件总线,这样更符合Vue中的命名规则

(1)安装全局事件总线:

new Vue({
    .....
    beforeCreate() {
        Vue.prototype.$bus = this //安装全局事件总线,$bus就是当前应用的vm
    }
})

(2)使用事件总线:

  • 接收数据:A组件想要接收数据,则在A组件中给$bus绑定自定义事件,事件的回调留在A组件自身
methods(){
    demo(data){......} //事件的回调函数
}
......
mounted() { //事件的回调留在自身
    this.$bus.$on('xxxx',this.demo)
}
  • 提供数据:this.$bus.$emit('xxx',数据)

5、最好在beforeDestroy钩子中,用$off去解绑当前组件所用到的事件。

案例

1、需求:点击按钮,School组件将学校地址通过全局总线传给Student组件。

2、实现:

  • main.js (安装全局事件总线)
/*
	该文件是整个项目的入口文件
*/
//引入Vue
import Vue from 'vue'
//引入App组件,它是所有组件的父组件
import App from './App.vue'

//管比vue产生的提示
Vue.config.productionTip = false

//创建vue实例对象 -- vm
new Vue({
	el:'#app',
	beforeCreate(){
		//安装全局事件总线,$bus就是当前应用的vm
		Vue.prototype.$bus = this
	},
	//下面这行代码一会解释,完成了这个功能:将App组件放入容器中
    render: h => h(App),
})

  • School.vue (提供数据)
<template>
	<!-- 组件的结构 -->
	<div class="school">
		<h2>学校姓名:{{name}}</h2>
		<h2>学校地址:{{address}}</h2>
		<!-- 触发提供数据的标签 -->
		<button @click="sendAddressToStudent">点击将学校地址传给学生</button>
	</div>
</template>

<script>
	export default {
		name:'School',
		data(){
			return {
				name:'尚硅谷atguigu',
				address:'北京',
			}
		},
		methods:{
			sendAddressToStudent(){
				//提供数据
				this.$bus.$emit('ToStudentAddress',this.address)
			}
		}
	}
</script>

<style scoped>
	.school{
		background: skyblue;
		padding: 5px;
	}
</style>
  • Student.vue (接收数据)
<template>
	<!-- 组件的结构 -->
	<div class="student">
		<h2>学生姓名:{{name}}</h2>
		<h2>学生性别:{{sex}}</h2>
	</div>
</template>

<script>
	export default {
		name:'Student',
		data(){
			return {
				name:'张三',
				sex:'男',
			}
		},
		methods:{
			//事件的回调函数
			getSchoolAddress(data){
				console.log('收到来自School的地址信息:',data)
			},
		},
		mounted(){
			//接收数据
			this.$bus.$on('ToStudentAddress',this.getSchoolAddress)
		}
	}
</script>

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

3、效果:点击按钮后发现Student收到数据

image.png