设计模式:订阅-发布模式以及Vue 中的 $on,$emit 的
2020-05-11 本文已影响0人
泰然自若_750f
什么是“订阅-发布模式”?
订阅-发布模式定义了对象之间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都可以得到通知。
订阅-发布模式” vs 观察者模式
订阅-发布模式和观察者模式概念相似,但在订阅-发布模式中,订阅者和发布者之间多了一层中间件:一个被抽象出来的信息调度中心。
https://www.jianshu.com/p/89d656db6548
代码实现
class Dep{
constructor(){
this.depsList=[];
}
/**
* 订阅
* @param {*} key 事件
* @param {*} component 组件
* @param {*} fn 回调
*/
on(key,component,fn){
if(typeof component!='object' || component===null)
{
throw TypeError('component 不合法');
}
let index=this.depsList.findIndex(item=>item.key===key);
if(index>=0)
{
this.depsList[index].callbacks.set(component,fn);
}
else{
var callbacks=new Map();
callbacks.set(component,fn);
this.depsList.push({key:key,callbacks:callbacks});
}
}
/**
* 发布
* @param {}} key
* @param {...any} props
*/
emit(key,...props){
//debugger
let deps=this.depsList.find(item=>item.key===key);
if(!deps) return;
for (let [component,fn] of (deps.callbacks)) {
fn.call(component,...props)
}
}
/**
* 取消订阅
* @param {*} key
* @param {*} component
*/
remove(key,component){
if(typeof component==='object' && component!=null)
{
let deps=this.depsList.find(item=>item.key===key);
if(!deps) return;
if(deps.callbacks.has(component))
{
deps.callbacks.delete(component);
}
}
else{
let index=this.depsList.findIndex(item=>item.key===key);
if(index!=-1)
{
this.depsList.splice(index,1)
}
}
}
}
let dep=new Dep();
class A {
}
class B {
}
let a=new A();
let b=new B();
//A 组件订阅
dep.on('click',a,(...props)=>{
console.log(`a 组件收到:${{...props}}`);
})
//B 组件订阅
dep.on('click',b,(...props)=>{
console.log(`b 组件收到:${{...props}}`);
})
//发布时间
dep.emit('click',a,b);
//移除A 组件上的订阅
dep.remove('click',a);
//全部移除
dep.remove('click');