vue事件总线 - EventBus
前言
在vue组件中,常见的有父子组件通信,兄弟组件通信等,但是如果两个页面没有任何引入和被引入关系,除了使用 vuex 来处理组件之间的数据通信,还可以考虑vue中的 事件总线(EventBus) 来通信。
一、简介
在vue中可以使用 EventBus 来作为 沟通桥梁 的概念,就像是所有组件共用相同的事件中心,可以向该中心注册 发送事件 或 接收事件,所以组件都可以 上下平行地 通知其他组件,但也就是太方便所以若使用不慎,就会造成难以维护的“灾难”。因此,我们通常情况下,还是会使用更完善的 vuex 作为状态管理中心,将通知的概念上升到 共享状态 层次。
二、使用
1. 整体思路
公共事件总线eventBus的实质就是:创建一个vue实例,通过一个空的vue实例作为桥梁 实现vue组件间的通信。它是实现非父子组件通信的一种解决方案。
2. 初始化
首先需要 创建事件总线并将其导出,以便其它模块可以使用或者监听它 。我们可以通过两种方式来处理。
第一种:创建一个js文件,命名为 event-bus.js,代码如下:
// 引入vue,创建一个vue实例,并导出这个实例
import Vue from 'vue'
export default new Vue()
第二种:直接在项目中的 main.js 初始化 EventBus ,代码如下:
Vue.prototype.$EventBus = new Vue()
注意:这种方式初始化的EventBus是一个全局的事件总线。
实质上 EventBus 是一个不具备 DOM 的组件,它具有的仅仅只是实例方法而已,因此它非常的轻便。
3. 引入event-bus
假设现在已有两个Vue页面需要通信: A 和 B ,现在需要先在页面中分别引入这个 event-bus.js:
A组件:
<template>
<div>
<h2>组件A</h2>
</div>
</template>
<script>
import EventBus from '@/js/event-bus'
export default {
name: 'A'
}
</script>
B组件:
<template>
<div>
<h2>组件B</h2>
</div>
</template>
<script>
import EventBus from '@/js/event-bus'
export default {
name: 'B'
}
</script>
4. 发送事件
我们在A页面的按钮上面绑定了点击事件,发送一则消息,想通知 B页面。
A组件:
<template>
<div>
<h2>组件A</h2>
<button @click="sendMsg">发送</button>
</div>
</template>
<script>
import EventBus from '@/js/event-bus'
export default {
name: 'A',
methods: {
sendMsg () {
// 通过vue实例方法$emit发送事件名称和需要传递的数据
EventBus.$emit('msgAHandler', 'hello world')
}
}
}
</script>
5. 接收事件
B组件:
<template>
<div>
<h2>组件B</h2>
<p>{{ msg }}</p>
</div>
</template>
<script>
import EventBus from '@/js/event-bus'
export default {
name: 'EventBusB',
data () {
return {
msg: ''
}
},
mounted () {
// 通过vue实例方法$on监听到事件和接受到数据
// 接收数据的组件,通常挂载监听在vue生命周期created和mounted当中
EventBus.$on('msgAHandler', (value) => {
this.msg = value
})
}
}
</script>
6. 移除事件监听者
vue是单页应用,如果在某一个页面刷新了之后,与之相关的EventBus会被移除,这样就导致业务走不下去。如果业务有反复操作的页面,EventBus 在监听的时候就会触发很多次,也是一个非常大的隐患。这时候我们就需要好好处理 EventBus 在项目中的关系。
所以通常在vue页面销毁时,同时要 移除EventBus事件监听。
在vue生命周期 beforeDestroy 或者 destroyed 中用vue实例的 $off 方法清除 eventBus,代码如下:
beforeDestroy(){
// 移除应用内所有对这个事件的监听
EventBus.$off('msgAHandler')
// 来移除所有事件频道,不需要添加任何参数
EventBus.$off()
}
总结
本文主要通过简单的实例学习了Vue中有关于 EventBus 相关的知识点。主要涉及了 EventBus 如何实例化,又是如何通过 $emit发送频道信号,又是如何通过 $on 来接收频道信号。从实例中我们可以了解到, EventBus 可以较好的实现兄弟组件之间的数据通讯。