在鸿蒙(HarmonyOS)开发中,父组件调用子组件方法
在鸿蒙(HarmonyOS)开发中,父组件调用子组件方法主要有以下三种主流方案,结合官方推荐和实际开发场景分析如下:
一、Controller 控制器模式(官方推荐)
通过定义控制器类实现父子组件解耦,适用于需要 同步调用 子组件方法的场景(如触发数据刷新、修改子组件状态等)。 实现步骤:
-
定义子组件控制器
javascriptexport class ChildController { refreshData: () => void = () => {}; // 定义空方法占位 }
-
子组件绑定控制器
typescript@Component struct ChildComponent { private controller: ChildController = new ChildController(); @State curPage: number = 1; aboutToAppear() { // 将子组件方法绑定到控制器 if (this.controller) { this.controller.refreshData = () => { this.curPage = 1; this.loadData(); // 子组件的实际业务方法 }; } } }
-
父组件调用控制器
less@Entry @Component struct ParentComponent { private childRef: ChildController = new ChildController(); build() { Column() { ChildComponent({ controller: this.childRef }) // 传递控制器 Button("刷新子组件数据") .onClick(() => { this.childRef.refreshData(); // 直接调用子组件方法 }) } } }
二、自定义事件调度器
通过静态类或全局事件管理实现跨组件通信,适用于 松耦合场景 (如隐藏弹窗、跨层级调用)。 实现示例:
-
定义事件调度类
javascriptexport class EventDispatcher { static hidePopup?: () => void; // 定义事件回调 static triggerHide() { if (this.hidePopup) { this.hidePopup(); // 触发子组件方法 } } }
-
子组件注册事件
ini@Component struct ChildComponent { @State showPopup: boolean = true; aboutToAppear() { EventDispatcher.hidePopup = () => { this.showPopup = false; // 绑定实际方法 }; } }
-
父组件触发事件
less@Entry @Component struct ParentComponent { build() { Button("关闭子组件弹窗") .onClick(() => { EventDispatcher.triggerHide(); // 触发全局事件 }) } }
适用场景 :跨层级组件通信,无需直接引用子组件实例(4 6)。
三、事件总线(Emitter/EventHub)
通过系统提供的 emitter
模块实现 一对多通信 ,适合复杂应用中的状态同步(如主题切换、全局配置更新)。 代码示例:
-
子组件监听事件
typescriptimport emitter from '@ohos.events.emitter'; @Component struct ChildComponent { onPageShow() { // 订阅事件 emitter.on("refreshEvent", (data) => { console.log("收到刷新指令:", data); }); } }
-
父组件发送事件
less@Entry @Component struct ParentComponent { sendEvent() { emitter.emit({ eventId: "refreshEvent", data: { page: 1 } // 携带参数 }); } }
特点 :支持异步、跨页面通信,但需注意事件命名规范和资源释放(7)。
四、方案选择建议
场景 | 推荐方案 | 理由 |
---|---|---|
直接同步调用 | Controller 模式 | 类型安全,代码直观(2 8) |
跨层级/解耦需求 | 自定义事件调度器 | 避免组件间强耦合(4 6) |
全局状态/一对多通知 | Emitter 事件总线 | 系统原生支持,适合复杂应用(7) |
注意事项
- 循环子组件处理 :若子组件通过
ForEach
动态生成,需将控制器声明为数组并按索引操作(3)。 - 编码规范:避免在子组件中直接暴露内部状态,优先通过方法封装业务逻辑。
- 性能优化:高频调用场景建议使用 Controller 模式,减少事件通信开销。