实现鸿蒙JS UI任意组件间通信 原创

中软陈乔
发布于 2021-8-4 10:07
浏览
0收藏

在鸿蒙JS UI组件间进行数据通信及事件的调用,对于父子组件关系可以使用props、$emit、$parent、$child等官方提供的方式来进行数据通信。
在app.js文件中定义的数据可以通过this.$app.$def获取,根据这个特性和使用观察者模式来开发一个可以全局发布订阅响应的通信管道。

  1. eventBus.js 代码
const Bus = {
    // 事件集合
    _events:{ },

    /**
     * 绑定事件
     * type: string 字符串
     * fun: function 绑定的方法
     * return: 返回绑定事件对应的标签,用于注销事件
     * */
    $on(type,fun){
        let res = "";
        if(type && typeof type == "string" && fun && typeof fun =="function"){
            let events = this._events[type];
            if(events){
                let index = events.findIndex(null);
                if(index > -1){
                    res = `${String(index)}${type}`;
                    events[index] = fun;
                }else{
                    events.push(fun);
                }
            }else{
                this._events[type] = [fun];
                res = `0${type}`;
            }
        }
        return res;
    },

    /**
     * 触发事件
     * type: string 发布事件的字符串
     * args: 传参
     * */
    $emit(type,...args){
        if(type && typeof type == "string"){
            let events = this._events[type];
            if(events){
                events.forEach(fun => {
                    if(fun && typeof fun =="function"){
                        fun(...args);
                    }
                });
            }
        }
    },

    /**
     * 注销事件方法
     * type: string 字符串
     * fun: string|function 发布事件时返回的值或者发布的原function
     * */
    $off(type,fun){
        if(type && typeof type == "string" && fun){
            let events = this._events[type];
            if(events){
                if(typeof fun == "string"){
                    let indexStr = fun.replace(type,'');
                    let index = parseInt(indexStr);
                    if(Number.isInteger(index)){
                        events[index] = null;
                    }
                }
                if(typeof fun == "function"){
                    events.forEach(item => {
                        if(item == fun){
                            item = null;
                        }
                    });
                }
            }
        }
    }
}
export default Bus;
  1. app.js引入
import Bus from "./common/js/eventBus.js"
export default {
    eventBus:Bus,
    onCreate() {
        console.info('AceApplication onCreate');
    },
    onDestroy() {
        console.info('AceApplication onDestroy');
    }
};

  1. 绑定事件
export default {
    data: {
        parentEvent: ""
    },
    // 初始化自定义组件
    onInit(){
        // 获取全局Bus
        let Bus = this.$app.$def.eventBus;
        // 绑定changeData事件
        this.parentEvent = Bus.$on('changeData', this.changeData);
    },
    // changeData
    changeData(data){
        console.log('changeData');
        console.log(data)
    }
}
  1. 触发事件
export default {
    data: { },
    // 触发在parent组件中绑定的事件
    busEmitParent(){        
        let Bus = this.$app.$def.eventBus;
        Bus.$emit('changeData', '123456789');
    }
}
  1. 注销事件
export default {
    data: {
        parentEvent: ""
    },
    // 初始化自定义组件
    onInit(){
        // 获取全局Bus
        let Bus = this.$app.$def.eventBus;
        // 绑定changeData事件
        this.parentEvent = Bus.$on('changeData', this.changeData);
    },
    // changeData
    changeData(data){
        console.log('changeData');
        console.log(data)
    },

    // 组件销毁时注销绑定的事件,有两种注销方式
    onDestroy(){
        let Bus = this.$app.$def.eventBus;

        // 使用 Bus.$on 方法的返回值注销,这种可以注销匿名函数的绑定
        if(this.parentEvent){
            Bus.$off('changeData',this.parentEvent);
        }

        // 直接使用绑定的changeData注销,直接注销绑定的方法
        // Bus.$off('changeData', this.changeData);
    }
}

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
eventBus.rar 760B 38次下载
TestApp.rar 4.22M 32次下载
已于2021-8-10 08:52:50修改
2
收藏
回复
举报
回复
    相关推荐