写点什么

鸿蒙应用示例:跨组件通信实践父组件调用子组件方法及状态共享

作者:zhongcx
  • 2024-10-12
    广东
  • 本文字数:2190 字

    阅读完需:约 7 分钟

在构建复杂的应用时,组件间的通信是一个常见的需求。HarmonyOS 提供了多种机制来实现这种通信,包括 emitter、eventHub 以及基于 @Provide、@Consume、@Watch 的响应式数据流。

参考官方文档:

【状态管理最佳实践】

https://developer.huawei.com/consumer/cn/doc/best-practices-V5/bpta-status-management-V5

【EventHub】

https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-inner-application-eventhub-V5

【emitter】

https://developer.huawei.com/consumer/cn/doc/harmonyos-references-V5/js-apis-emitter-V5#emitteron


以下是我常用的方式总结

方案一:自定义事件调度器

自定义事件调度器是一种简单有效的通信方式,它通过定义静态方法来管理事件的发送和接收。这种方式的好处在于其实现相对直接,不需要依赖外部框架。

示例代码:

class EventDispatcher {  static childCallback?: (value: number) => void;
static dispatchToChild(value: number) { if (EventDispatcher.childCallback) { EventDispatcher.childCallback(value); } }}
@Componentstruct ChildComponent { @State value: string = ""
aboutToAppear(): void { EventDispatcher.childCallback = (value: number) => { this.handleChildMethod(value); }; }
handleChildMethod(value: number) { console.info('我是子组件方法', '父组件传递的值为:' + value); this.value = String(value) }
build() { Column() { Text(`我是子组件,父组件传递的内容是:${this.value}`) }.width('100%'); }}
@Entry@Componentstruct Index { build() { Column() { Button('调用子组件方法').onClick(() => { EventDispatcher.dispatchToChild(33); });
ChildComponent(); } .width('100%'); }}
复制代码

方案二:使用 emitter

emitter 是一种更为动态的事件管理方式,它可以绑定事件处理函数,并在特定条件下触发这些处理函数。这种方法适用于需要在不同组件间传递复杂数据的情况。

示例代码:

import { emitter } from '@kit.BasicServicesKit';
@Componentstruct ChildComponent { @State value:number = 0 aboutToAppear(): void { emitter.on({ eventId: 1 }, (event) => { if (event.data && event.data.data) { this.handleChildMethod(event.data.data as number); this.value = event.data.data } }); }
handleChildMethod(value: number) { console.info('我是子组件方法', '父组件传递的值为:' + value); }
build() { Column() { Text(`我是子组件,父组件传递的值为:${this.value}`) }.width('100%'); }}
@Entry@Componentstruct Index { build() { Column() { Button('调用子组件方法').onClick(() => { emitter.emit( { eventId: 1, priority: emitter.EventPriority.IMMEDIATE }, { data: { 'data': 33 } } ); });
ChildComponent(); } .width('100%'); }}
复制代码

方案三:使用 eventHub

eventHub 是另一种事件管理机制,它允许组件间通过事件名来进行通信。相比前两种方法,它可能更接近 Vue.js 的事件总线模式。

示例代码:

@Componentstruct ChildComponent {  @State value :number = -1  aboutToAppear(): void {    getContext(this).eventHub.on('1', (data: number) => {      this.handleChildMethod(data as number);    });  }
handleChildMethod(value: number) { console.info('我是子组件方法', '父组件传递的值为:' + value); this.value = value }
build() { Column() { Text(`我是子组件,父组件传递的值为:${this.value}`) }.width('100%'); }}
@Entry@Componentstruct Index { build() { Column() { Button('调用子组件方法').onClick(() => { getContext(this).eventHub.emit('1', 33); });
ChildComponent(); } .width('100%'); }}
复制代码

方案四:基于 @Provide、@Consume、@Watch 的数据共享

对于更高级的数据共享需求,HarmonyOS 提供了 @Provide、@Consume 和 @Watch 注解。这些注解可以用来在父子组件间共享状态,并且可以监听状态变化来自动更新 UI。

示例代码:

@Componentstruct Page012Child {  @Consume @Watch('onDataChanged') array: Array<Object>  @Consume @Watch('onDataChanged') index: number
build() { Column() { Text(`array:${JSON.stringify(this.array)}`) Text(`index:${this.index}`) Text(`每次this.index变化时,自定义onDataChanged方法会回调,注意首次不会回调`) } }
onDataChanged() { console.info('====onDataChanged') }}
@Entry@Componentstruct Page012 { @Provide array: Array<Object> = new Array<Object>() @Provide index: number = 0
build() { Column() { Button('测试').onClick(() => { this.array.push("abc") this.index++ })
Page012Child() } .width('100%') .height('100%') }}
复制代码


用户头像

zhongcx

关注

还未添加个人签名 2024-09-27 加入

还未添加个人简介

评论

发布
暂无评论
鸿蒙应用示例:跨组件通信实践父组件调用子组件方法及状态共享_zhongcx_InfoQ写作社区