一个组件库引发的发布者订阅者模式

99 阅读1分钟

首先安利一波组件库 zgy-ui 采用VitePress

起因是在开发UI组件库 Form表单 共有两个组件 一个Form 一个FormItem 状态之间需要共享和能够相互调用 采用slot 利用slot-scoped进行传参也勉强能用 奈何代码量过大,子父以及祖孙之间代码传递复杂 增加不可维护性

先贴一张最终实现效果 Form表单

76bbb7ffcffedb516b1d057beb41669.jpg

此组件已经开发完毕 并已更新组件库 V 1.0.47

组件文档还未来得及更新 后续会跟上

在找解决方案时 试了存Window 试了存缓存 试了Pinan VueX等状态管理 效果都不是很理想,要么是方法Low 要么是需要额外引入js库

考虑到后期开发其它组件也会用到相关 就采用了EventBus

实现代码如下:
说白了就是 一个监听器 一个触发器 先监听后触发

class EventBus{
        
        constructor(){
            this._eventList = {}
        }

        static Instance(){
            if(!EventBus._instance){
                Object.defineProperty(EventBus,'_instance',{
                    value:new EventBus()
                })
            }
            return EventBus._instance;
        }

        on(type,cb){
            if(!this.isKeyInObj(this._eventList,type)){
                Object.defineProperty(this._eventList,type,{
                    value:[],
                    writable:true,
                    enumerable:true,
                    configurable:true
                })
            }
            this._eventList[type].push(cb)
        }

        emit(type,params){
            if(this.isKeyInObj(this._eventList,type)){
                for(let i=0;i<this._eventList[type].length;i++){
                    this._eventList[type][i] && this._eventList[type][i](params)
                }
            }
        }

        off(type,fn){
            if(this.isKeyInObj(this._eventList,type)){
                for(let i=0;i<this._eventList[type];i++){
                    if(this._eventList[type][i] && this._eventList[type][i] === fn){
                        this._eventList[type][i] = null;
                    }
                }
            }
        }

        isKeyInObj(obj, key) {
            if (Object.hasOwnProperty.call(obj, key)) {
                return true
            }
            return false
        }

    }