该文章已同步收录到我的博客网站,欢迎浏览我的博客网站,xhang’s blog
一:全局事件总线概述
1.全局事件总线是一种可以在任意组件间通信的方式,本质上就是一个对象。它必须满足以下条件:
1. 所有的组件对象都必须能看见他
2. 这个对象必须能够使用$on , $off 和 $emit方法去绑定、触发和解绑事件
二:安装全局事件总线
安装全局事件总线前需要考虑:如果要所有组件对象都能够获取到事件总线,那么将事件总线安装到哪里合适?从下图可以看出,当组件实例化对象vc获取数据时,会首先找到组件原型对象,如果该组件实例对象中没有此数据,那么就找到Vue的原型对象,Vue的原型对象只有一个,所有组件都能够获取到它的数据,所以事件总线要安装到Vue的原型对象上。
由于是在入口文件main.js中引入的Vue,所以事件总线需要配置到main.js当中
// 引入Vue
import Vue from "vue";
// 引入App组件
import App from './App.vue'
// 关闭生产提示
Vue.config.productionTip = false
// 创建vm对象
new Vue({
el:'#app',
render:h => h(App),
// 配置全局事件总线
beforeCreate(){
// this表示当前Vue实例
Vue.prototype.$bus = this
}
})
为什要在Vue实例对象中采用生命周期钩子beforeCreate安装事件总线?
由生命周期beforeCreate此时只是完成了初始化工作,创建了Vue实例对象,但是模板并没有解析,数据代理并没有运转。
其他几种安装位置分析
一:在创建vm实例对象前创建事件总线
当前Vue实例对象并没有创建,无法在Vue实例对象中通过Vue原型对象安装事件总线。
二:在创建vm实例对象后创建事件总线
当前Vue实例对象生命周期已经完成,模板已经解析,数据代理已经完成。
综上所述,安装事件总线的位置应是在Vue实例对象的beforeCreate钩子中完成事件总线的安装
三:使用全局事件总线
使用全局事件总线可以完成任何组件之间的数据交互,如完成兄弟组件之间的数据交互。
测试:将Student组件当中的学生名传递给School组件(Student组件向School组件传递数据)
即在School组件当中向全局事件总线中绑定事件,由Student组件触发并传递数据
School组件
<template>
<div class="test">
<h2>学校名称:{{ name }}</h2>
<h2>地址:{{ address }}</h2>
</div>
</template>
<script>
export default {
name: "School",
data() {
return {
name: "张三大学",
address: "PDS",
};
},
methods:{
getStudentName(data){
console.log('我是School组件,从Student组件中接收到的数据为:'+data);
}
},
mounted() {
// 向事件总线中绑定事件,事件名为studentName
this.$bus.$on('studentName',this.getStudentName)
},
//当销毁组件前,销毁该组件中的事件,避免全局事件总线中事件名被无效占用
beforeDestroy(){
this.$bus.$off('studentName')
}
};
</script>
Student组件
<template>
<div class="test">
<h2>学号:{{ id }}</h2>
<h2>姓名:{{ name }}</h2>
<button @click="sendStudentName">向School组件传递学生名</button>
</div>
</template>
<script>
export default {
name: "Student",
data() {
return {
id: "201530326",
name: "枫原万叶",
};
},
methods:{
sendStudentName(){
//触发全局事件总线中的事件studentName并传参
this.$bus.$emit('studentName',this.name)
}
}
};
</script>
测试结果