
vue 自己带了一个简易的 pub/sub 工具 bus
对于简单的数据通信来说这已经足够使用.vuex 这种相对来说标准化更高, 对于 大型团队和复杂项目来使用相对才能 看出好处
自制一个
不管 redux/nodejs 还是啥,这种消极机制在开发中经常会看到.
-
消息队列
-
redis
-
反应式编程库
-
各种 agent 和 数据通信的调度
核心插件代码:
1import Vue, { PluginFunction } from "vue" 2 3class Hub { 4 // 内置事件队列 5 private queue: Map<string, Map<Symbol, Function>> = new Map() 6 7 // 注册事件 8 on(eventName: string, fn: Function) { 9 const handler = Symbol(fn.name)10 if (this.queue.get(eventName)) {11 this.queue.get(eventName)!.set(handler, fn)12 } else {13 this.queue.set(eventName, new Map().set(handler, fn))14 }15 return handler16 }17 //事件触发18 emit(eventName: string, payload: any) {19 for (const iterator of this.queue.get(eventName)!.values()) {20 setTimeout(()=>{21 iterator(payload)22 },0)23 }24 }25 // 取消订阅26 off(eventName: string, handler: Symbol) {27 this.queue.get(eventName)!.delete(handler)28 }29}30// 暂时只用单例31const instance = new Hub()32let HubPlugin: any = {}33HubPlugin.install = function(Vue: any, options: object) {34 Vue.prototype.$hub = instance35}36// 以插件形式暴露37export default HubPlugin
使用
-
main.ts 引入插件
1import HubPlugin from "@/utils/hub"2Vue.use(HubPlugin)3...
-
组件中注册事件
1 methods: { 2 testV(m) { 3 console.log("from form page", m) 4 this.form.name = m 5 } 6 }, 7 created() { 8 let xx = this.$hub.on("test", this.testV) 9 console.log(xx, ":xx")10 }11 }
-
需要监听的地方订阅消息
1export default { 2 data() { 3 return { 4 name: "" 5 } 6 }, 7 methods: { 8 trigger() { 9 this.$hub.emit("test", "great")10 },11 testV(m) {12 console.log("from about page", m)13 this.name = m14 }15 },16 created() {17 this.h = this.$hub.on("test", this.testV)18 this.h2 = this.$hub.on("test", () => {19 console.log("object")20 })21 this.$hub.off("test", this.h)22 this.$hub.off("test", this.h2)23 }24}
总结:
-
on 注册事件和 callback,获取句柄
-
off 用句柄取消订阅
-
emit 触发消息
对于本组件订阅的消息,请自行在 beforeDestroy 中取消订阅, 以免无畏的内存消耗