Vue - 自制bus

vue 自己带了一个简易的 pub/sub 工具 bus

对于简单的数据通信来说这已经足够使用.
vuex 这种相对来说标准化更高, 对于  大型团队和复杂项目来使用相对才能  看出好处

自制一个

不管 redux/nodejs 还是啥,这种消极机制在开发中经常会看到.

  • 消息队列
  • redis
  • 反应式编程库
  • 各种 agent 和  数据通信的调度

 核心插件代码:

import Vue, { PluginFunction } from "vue"

class Hub {
// 内置事件队列
private queue: Map<string, Map<Symbol, Function>> = new Map()

// 注册事件
on(eventName: string, fn: Function) {
const handler = Symbol(fn.name)
if (this.queue.get(eventName)) {
this.queue.get(eventName)!.set(handler, fn)
} else {
this.queue.set(eventName, new Map().set(handler, fn))
}
return handler
}
//事件触发
emit(eventName: string, payload: any) {
for (const iterator of this.queue.get(eventName)!.values()) {
setTimeout(()=>{
iterator(payload)
},0)
}
}
// 取消订阅
off(eventName: string, handler: Symbol) {
this.queue.get(eventName)!.delete(handler)
}
}
// 暂时只用单例
const instance = new Hub()
let HubPlugin: any = {}
HubPlugin.install = function(Vue: any, options: object) {
Vue.prototype.$hub = instance
}
// 以插件形式暴露
export default HubPlugin

使用

  1. main.ts 引入插件
import HubPlugin from "@/utils/hub"
Vue.use(HubPlugin)
...
  1. 组件中注册事件
methods: {
testV(m) {
console.log("from form page", m)
this.form.name = m
}
},
created() {
let xx = this.$hub.on("test", this.testV)
console.log(xx, ":xx")
}
}
  1. 需要监听的地方订阅消息
export default {
data() {
return {
name: ""
}
},
methods: {
trigger() {
this.$hub.emit("test", "great")
},
testV(m) {
console.log("from about page", m)
this.name = m
}
},
created() {
this.h = this.$hub.on("test", this.testV)
this.h2 = this.$hub.on("test", () => {
console.log("object")
})
this.$hub.off("test", this.h)
this.$hub.off("test", this.h2)
}
}

总结:

  • on 注册事件和 callback,获取句柄
  • off 用句柄取消订阅
  • emit 触发消息

对于本组件订阅的消息,请自行在 beforeDestroy 中取消订阅, 以免无畏的内存消耗