Vue3中Bus总线的实现

485 阅读1分钟

背景

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")