美文网首页
设计模式:订阅-发布模式以及Vue 中的 $on,$emit 的

设计模式:订阅-发布模式以及Vue 中的 $on,$emit 的

作者: 泰然自若_750f | 来源:发表于2020-05-11 10:49 被阅读0次

    什么是“订阅-发布模式”?

    订阅-发布模式定义了对象之间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都可以得到通知。

    订阅-发布模式” 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');
    

    执行结果

    image.png

    相关文章

      网友评论

          本文标题:设计模式:订阅-发布模式以及Vue 中的 $on,$emit 的

          本文链接:https://www.haomeiwen.com/subject/znwynhtx.html