今天,我借这篇文章带大家回顾一下发布-订阅模式。这时候可能有朋友会说,当然不是!不然还没开始就结束了?嗯,Pi对此还挺高兴的,那么进入正题吧!##简介相信我们很多人都用过vue框架,也用过它的跨组件通信方案EventBus(事件总线)。如果你没用过也没关系。其实它还有3个常用的API。@on(event:string,cb:function)monitor@emit(event:string,...args:any[])trigger@off(event,cb:function)unlisten我想引入EventBus不是因为我想用它解决了我们浏览器标签页之间的通信,接下来我们就要用它的使用方法来实现我们的通信了!初步代码编译成talkischeap,给我看看代码。一开始在项目中只是简单的使用类的方法来实现这个机制。这里笔者使用localStorage触发更新的功能来实现发布订阅机制,但是受限于这个API只能和同一个源通信,同一个tab的更新不会触发相应的监听事件.我们绑定的监控函数只有一个,但是每次触发都会检查对应的监控事件是否触发,如果触发了就找对应的cb回调/***eventbus*based关于postMessage的设计,目的是解决多个tab之间的通信*/classEventBus{constructor(){//初始化订阅事件对象this.subscribes={};window.addEventListener('storage',this.handlerMethod.bind(this));}handlerMethod(e){const{key:event,newValue}=e;//localStorage没有字段,或者直接返回if(!localStorage.getItem(event)||!this.subscribes[event])return;//删除也会触发if(!newValue)return;让数据=空;尝试{data=JSON.parse(newValue);}catch(error){console.log('这是数据解析错误');}this.subscribes[event].forEach(cb=>{cb&&cb(data);});}//listenon(event,cb){this.subscribes[event]=(this.subscribes[event]||[]).concat(cb);localStorage.setItem(event,'init');}//Listenonce(event,cb){constfun=()=>{cb&&cb();this.off(事件,乐趣);};this.on(事件,乐趣);}//deleteoff(event,callback){(this.subscribes[event]||[]).forEach((cb,i)=>{if(cb===callback){this.subscribes[event].splice(i,1);localStorage.removeItem(event);}});}offAll(){Object.keys(this.subscribes).forEach(event=>{deletethis.subscribes[event];localStorage.removeItem(event);});}/*eslint-disable*/emit(event,payload){//如果只是简单的触发器不传参,给一个随机数localStorage.setItem(event,payload?JSON.stringify(payload):Math.random());}/*eslint-enable*/}exportdefault{install(Vue){Vue.prototype.$eventBus=newEventBus();},};使用上面的代码可以直接在你的项目中main.jsimportVuefrom'vue'importeventButfrom'./my-eventBus';Vue.use(eventBut)functioncb(...args){console.log(参数)<!--监听事件-->Vue.$eventBus.on('someEvent',cb)Vue.$eventBus.emit('someEvent','hello')enhance加强上面things已经满足需求了,但是人生无止境,折腾~总不能到处复制粘贴吧!?所以我封装成一个npm包//yarnaddenhance-eventbus或者npmi-Senhance-eventbus使用起来也很方便。压缩后的代码只有1kb。对于ts??项目,在main.js中有对应的APITip~//importenhanceEventbusfrom"enhance-eventbus"importVuefrom"vue"Vue.use(enhanceEventbus,{type:"storage",globalKey:"$eventBus"//这里配置的是vue.prototype挂载的属性名称是什么})//然后你可以通过你定义的gloalKey来使用它newVue({mounted(){this.$eventBus.on('someEvent',(data)=>{//...todosth})this.$eventBus.emit('someEvent',data)}})最后看一下用法示例~~然后,不要脸的问对于一个明星https://github.com/cjfff/enha...
