前言
vue 组件中的数据传递最最常见的就是父子组件之间的传递。父传子通过 props 向下传递数据给子组件;子传父通过 $emit 发送事件,并携带数据给父组件。而有时两个组件之间毫无关系,或者他们之间的结构复杂,如何传递数据呢?这时就要用到 vue 中的事件总线 EventBus 的概念
- 公众号: 前端印象
- 不定时有送书流动,记得关注~
- 关注后回复对应文字支付:【面试题】、【前端必看电子书】、【数据结构与算法残缺代码】、【前端技术交换群】
注释
EventBus 的简介
EventBus 又称事件总线,相当于一个全局的仓库,任何组件都能够去这个仓库里获取事件,如图:
EventBus 的应用
废话不多说,间接开始应用 EventBus
一、初始化
要用 EventBus,首先要初始化一个 EventBus,这里称它为全局事件总线。
- 第一种初始化办法
import Vue from 'vue'
// 因为是全局的一个 '仓库',所以初始化要在全局初始化
const EventBus = new Vue()
- 第二种初始化办法 (本文选用这种初始化办法)
// 在曾经创立好的 Vue 实例原型中创立一个 EventBus
Vue.prototype.$EventBus = new Vue()
二、向 EventBus 发送事件
发送事件的语法:this.$EventBus.$emit(发送的事件名, 传递的参数)
曾经创立好 EventBus 后咱们就须要向它发送须要传递的事件,以便其余组件能够向 EventBus 获取。
例子:有两个组件 A 和 B 须要通信,他们不是父子组件关系,B 事件须要取得 A 事件里的一组数据 data
<!-- A.vue 这里是以模块化的形式解说的,即 A 组件和 B 组件别离各自
一个.vue 文件, 所以代码中会有导入的语法 -->
<template>
<button @click="sendMsg"> 发送 MsgA</button>
</template>
<script>
export default {data(){
return{MsgA: 'A 组件中的 Msg'}
},
methods: {sendMsg() {
/* 调用全局 Vue 实例中的 $EventBus 事件总线中的 $emit 属性,发送事
件 "aMsg", 并携带 A 组件中的 Msg*/
this.$EventBus.$emit("aMsg", this.MsgA);
}
}
};
</script>
三、接管事件
接管事件的语法:this.$EventBus.$on(监听的事件名, 回调函数)
A 组件曾经向全局事件总线 EventBus 发送了一个 aMsg 事件,这时 B 组件就能够去 aMsg 监听这个事件,并能够取得一些数据。
<!-- B.vue -->
<template>
<!-- 展现 msgB -->
<p>{{msgB}}</p>
</template>
<script>
export default {data(){
return {
// 初始化一个 msgB
msgB: ''
}
},
mounted() {
/* 调用全局 Vue 实例中的 $EventBus 事件总线中的 $on 属性, 监听 A 组件发送
到事件总线中的 aMsg 事件 */
this.$EventBus.$on("aMsg", (data) => {
// 将 A 组件传递过去的参数 data 赋值给 msgB
this.msgB = data;
});
}
};
</script>
B 组件展现后果:
A 组件中的 Msg
这样,B 组件就轻松接管到了 A 组件传递过去的参数,并胜利展现了该参数,这样是不是就很简略的解决了各组件之间的通信呢?尽管 EventBus 是一个很轻便的办法,任何数据都能够往里传,而后被别的组件获取,然而如果用不好,容易呈现很重大的 BUG,所以接下来咱们就来解说一下移除监听事件。
四、移除监听事件
在上一个例子中,咱们 A 组件向事件总线发送了一个事件 aMsg 并传递了参数 MsgA,而后 B 组件对该事件进行了监听,并获取了传递过去的参数。然而,这时如果咱们来到 B 组件,而后再次进入 B 组件时,又会触发一次对事件 aMsg 的监听,这时工夫总线里就有两个监听了,如果重复进入 B 组件屡次,那么就会对 aMsg 进行屡次的监听。
总而言之,A 组件只向 EventBus 发送了一次事件,但 B 组件却进行了屡次监听,EventBus 容器中有很多个截然不同的事件监听器这时就会呈现,事件只触发一次,但监听事件中的回调函数执行了很屡次
- 解决办法:在组件来到,也就是被销毁前,将该监听事件给移除,免得下次再反复创立监听
- 语法:
this.$EventBus.$off(要移除监听的事件名)
<!-- B.vue -->
<template>
<!-- 展现 msgB -->
<p>{{msgB}}</p>
</template>
<script>
export default {data(){
return {
// 初始化一个 msgB
msgB: ''
}
},
mounted() {
/* 调用全局 Vue 实例中的 $EventBus 事件总线中的 $on 属性, 监听 A 组件发送
到事件总线中的 aMsg 事件 */
this.$EventBus.$on("aMsg", (data) => {
// 将 A 组件传递过去的参数 data 赋值给 msgB
this.msgB = data;
});
},
beforeDestroy(){
// 移除监听事件 "aMsg"
this.$EventBus.$off("aMsg")
}
};
</script>
结束语
好了,对于 vue 中的事件总线的解说就到这里了,这也是我明天在做我的项目时用到的一个小知识点,接下来附上一张我因为没有及时移除事件监听,导致我每重进组件一次就报错 48 条错误信息的图,心愿大家在我的文章中能血啊都一些货色,并且不要再犯我的这种低级谬误。