背景
Vue2中存在许多用于解决组件之间通信的方案,props,observable,$emit,Vuex,Bus等等。Bus总线是一套用于解决组件之间相互通信的方案。在Vue2中内置了Bus总线,而在Vue3中被删除了,今天在重构以前写的Vue2项目的时候发现了盲点。既然Bus总线没了,就自己写一个。
Vue2中Bus总线的使用方式
//bus.js
import Vue from 'vue'
const bus = new Vue()
export default bus
// A组件
import Bus from "./bus.js"
Bus.$emit("father", "title");
// B组件
Bus.$on("father", (msg)=>{
console.log(msg)
})
Bus.$off("father")
简单的说就是new一个全局的Vue实例,在B组件中监听A组件发出来的自定义事件来拿到A组件的数据。
Vue3中重构
// bus.ts
type objFun = {
[key:string]:Function
}
type funArr = Array<objFun>
class Bus{
// 事件队列
eventArr:funArr = []
$on(onevent:string, cb:Function) {
//判断数组中是否存在监听函数
let test = this.eventArr.find(item => item[onevent])
//如果存在,则覆盖
if (test) {
test[onevent] = cb
} else {
//否则创建一个新的监听函数
let obj = Object.create(null)
obj[onevent] = cb
// 将事件对象push到事件队列中
this.eventArr.push(obj)
}
}
$emit(emitevent:string, msg?:any) {
//每次发布的时候遍历数组,执行对应的监听函数
this.eventArr.find(item => item[emitevent])?.[emitevent](msg)
}
$off(emitevent:string){
// 一般在组件销毁的时候调用,删除事件队列中的事件
let eventIndex = this.eventArr.findIndex(item => item[emitevent])
eventIndex&&this.eventArr.splice(eventIndex,1)
}
}
export default new Bus
使用
import Bus from "./bus"
// A组件
import Bus from "./bus.js"
Bus.$emit("father", "title");
// B组件
Bus.$on("father", (msg)=>{
console.log(msg)
})
Bus.$off("father")