更多内容请访问:HarmonyOS技术社区https://harmonyos.51cto.com组件间通信的主要功能是在组件之间传递数据或者执行相关的业务逻辑,对于鸿蒙应用组件,下面会实现几个组件间通信方法的代码实现,包括任意组件通信的自定义实现的实现。文件结构首先我们准备几个组件parent组件,current组件,child1组件,child2组件,其中parent和current是父子组件关系,curren和child1/child2是父子组件关系,child1和child2是兄弟组件关系,parent和child1/child2是跨级组件的关系。详细代码文件请参考附件源码。最终预览结果如下:父子关系通信parent和current是父子组件关系。在current.js中,propstitle=''current-title",当parent.hml中使用当前组件,传入title="parent"时,当前组件显示parent。这里props是用来传达标题的父组件传给子组件的值,预览结果如下图所示:current和child1/child2是父子组件关系,在当前组件中,有三个按钮分别是changeparent,changechild1,和changechild2按钮配置如下:在当前组件中,点击changeparent按钮会触发changeParent方法,点击changechild1按钮会触发changeChild1方法,点击changingchild1按钮会触发changeChild1方法,该方法会更改相应组件中的数据,如下:点击更改父级按钮,使用$parent方法获取父组件的实例,然后与父组件进行数据通信通过实例对象:点击更改child1,通过$child方法获取child1组件实例,然后通过实例对象与child1组件进行数据通信:点击更改child2,获取child2组件实例通过使用$child方法,然后通过实例对象与child2组件进行数据通信:在changeParent方法中,通过this.$parent()方法获取父组件的ViewModel,使得数据可以访问和更改父组件的。在changeChild1和changeChild2中,通过this.$child(id)方法获取child1/child2组件。ViewModel,这样除了可以使用this.$parent方法外,还可以访问和更改child1/child2组件的数据自定义事件的方式是让子组件调用父组件的方法将值传递给父组件。父组件在引用当前组件时绑定事件,在当前组件中调用this.$emit方法触发绑定的自定义事件.js触发eventEmit方法:总结一下,父子组件之间通信大概有几种方法:props:用于父组件向子组件传递数据$emit:用于将数据从组件传递给父组件组件或调用父组件方法$parent:用于获取父组件ViewModel修改父组件数据并调用父组件方法$child:用于获取子组件ViewModel修改子组件数据并调用子组件方法Sibling跨级组件之间的关系和通信按照上面父子组件之间的通信方式,对于兄弟组件和cross级组件,结合以上方法可以实现非父子组件。通信,但是如果组件之间的嵌套比较复杂,嵌套层次很多,那么组合使用上述方法显然不方便。这里我们尝试实现一个类似于vuebus的全局通信方式来进行任意组件之间的通信。JSAPI中app.js文件中定义的数据可以通过this.app.app.def获取。根据这个特点和观察者模式,设计了一种可以全局订阅响应的通信模式。eventBus首先我们定义evnetBus.js文件,在里面定义订阅、发布、取消订阅的相关方法:constBus={//发布事件集合$events:{},/***发布事件方法*type:stringcharacterString*fun:函数绑定方法**/$on(type,fun){},/***触发事件方法*type:string释放事件字符串*args:传递参数**/$emit(type,...args){},/***注销事件方法*type:string*fun:string|function释放事件或释放原函数时的返回值**/$off(type,fun){}}exportdefaultBus;在里面,我们定义了$events对象用于存储绑定事件,$on方法用于绑定事件,$emit方法用于触发事件,$off方法用于注销事件,完整的eventBus.js如下:eventBus.jsconstBus={//Published事件集合$events:{},/***发布事件方法*type:string字符串*fun:函数绑定方法**/$on(type,fun){letres="";if(type&&typeoftype=="string"&&fun&& typeoffun =="function"){letevents=this.$events[type];if(events){letindex=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}`;}}returnres;},/***触发事件方法*type:string事件发布字符串*args:传递参数**/$发出(类型,...args){if(类型&&typeoftype="string"){letevents=this.$events[type];if(events){events.forEach(fun=>{if(fun&& typeoffun =="function"){fun(...args);}});}}},/***注销事件方法*type:string*fun:string|function释放事件或发布原函数时的返回值**/$off(type,fun){if(type&&typeoftype=="string"&&fun){letevents=this.$events[type];if(events){if(typeoffun=="string"){letindexStr=fun.replace(type,'');letindex=parseInt(indexStr);events[index]=null;}if(typeoffun=="function"){events.forEach(item=>{if(item==fun){item=null;}});}}}}}exportdefaultBus;使用方法介绍首先在app.js中引入eventBus,将eventBus绑定到我们的全局对象:在父组件的onInit方法中绑定事件,可以通过绑定的事件改变父组件的值,使用this.$app.$def方法获取全局app下挂载的eventBus对象:trigger然后我们修改child1组件,添加一个按钮使用eventBus对象的$emit方法触发总线事件:when触发方法,我们传入自己定义的参数数据“123456789”会触发我们在父组件中绑定的方法,点击按钮后改变父组件的数据,同时也接收到子组件传来的数据“123456789”component实现跨级组件。通信,这个方法可以有效的用于任意组件之间的事件触发和传值,限于篇幅就不展示了,最后我们要在组件销毁的时候取消我们绑定的事件Logout我们定义一个注销事件的按钮,并绑定注销事件:我们在$on绑定事件的时候可以得到一个返回值,这个值也可以用于事件注销,这里就不演示了,如果你有兴趣可以下去试试。综上所述,以上就是使用观察者模式实现了一个简单版的事件总线机制,可以实现任意组件之间的通信,基本功能都可以实现。还有一些不足需要提醒一下:首先this在使用的时候必须依赖鸿蒙JSAPIthis.$app.$def每次获取eventBus对象都要用到这个方法。注册绑定事件后,一定要记得在当前组件销毁时取消绑定事件,否则可能会造成内存泄漏。注销事件有两种方式,需要了解注销事件的原理才能熟练使用。更多信息请访问:Harmonyos.51cto.com,与华为官方合作打造的鸿蒙技术社区
