全局事件总线介绍
1、作用:一种组件之间通信的方式,适用于任意组件之间通信,原理图如下:
2、对上图中x的要求:
(1)保证所有组件都能看到x
(2)能调用到 $on(), $off(), $emit() 方法
3、分析如何设置全局事件总线:首先要满足以上两点要求,可以借助Vue原型对象来实现,因为VueComponent.prototype.__proto__ === Vue.prototype这个重要的内置关系。如果我们在Vue原型上添加总线,那么所有组件都能访问到这个总线。也就是说我们要将组件加在下图中红色框框里。
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收到数据