一种组件间的通信方式
任意组件间通信
beforeCreate() {
Vue.prototype.$bus = this;
}
假设全局事件总线为x
① 全局
想要任意组件都能看到,那么代码必须写在main.js入口文件中
② 事件总线
既然是事件,那么必须能调用绑定事件$on
,触发事件$emit
和解绑事件$off
,而Vue实例对象vm和VueComponent组件实例对象身上刚好有这些属性
① 推理1
通过VuComponent组件实例对象实现全局事件总线
//1、创建VueComponent组件
const VueComponent = Vue.extend({});
//2、得到VueComponent实例对象vc
const vc = new VueComponent();
//组件实例对象vc可以访问到Vue原型上的属性和方法(x为全局事件总线)
Vue.prototype.x=vc;
new Vue({
render:h=>h(App),
}).$mount("#app")
以上代码可以实现全局事件总线功能
② 推理2
通过Vue实例对象vm实现全局事件总线
//1、创建
const vm=new Vue({
render:h=>h(App),
}).$mount("#app")
Vue.prototype.x=vm
以上代码行不通,原因:当读取到render:h=>h(App),时,代码实现App等组件挂载到页面,最后再添加x,会导致页面报错
改进
new Vue({
//这个钩子时期,Vue已创建实例对象vm,数据还没绑定
beforeCreate(){
//这里的this指vm实例对象
Vue.prototype.x=this;
},
render:h=>h(App),
}).$mount("#app")
以上代码实现全局事件总线的功能,在vue官方文档中,全局事件总线用$bus表示,因此全局事件总线为以下代码
beforeCreate() {
Vue.prototype.$bus = this;
}
需求:通过全局事件总线实现兄弟间传数据(School组件接收来自Student组件的数据)
School组件
<template>
<div>
<p>学校名称:{{name}}p>
<p>学校地址:{{adress}}p>
<p>School组件接收到的学生姓名是:{{sName}}p>
div>
template>
<script>
export default {
name:"School",
data(){
return {
name:"喵喵学院",
adress:"郑州",
sName:""
}
},
mounted(){
//接收数据,绑定自定义事件getName
this.$bus.$on("getName",(name)=>[
this.sName=name
])
},
//解绑事件
beforeDestroy(){
this.$bus.$off("getName")
}
}
script>
Student组件
<template>
<div>
<p>学生性别是:{{sex}}p>
<button @click="sendMsg">点击向School发送学生姓名button>
div>
template>
<script>
export default {
name:"Student",
data(){
return {
name:"憨瓜",
sex:"男"
}
},
methods:{
sendMsg(){
//发送数据,触发自定义事件getName
this.$bus.$emit("getName",this.name)
}
}
}
script>
new Vue({
...
beforeCreate(){
Vue.prototype.$bus=this;
},
}).$mount("#app")
①接收数据
哪个组件要接收数据,在哪个组件里给$bus绑定自定义事件
mounted(){
this.$bus.$on("自定义事件",回调函数)
}
②提供数据
this.$bus.$emit("自定义事件",数据)
在哪个组件里绑定的自定义事件,在哪个里面解绑
beforeDestroy(){
this.$bus.$off("自定义事件")
}