
055 — 组件间通信方案对比EventBus / emitter / props 的选择策略简介在多模块、多组件的前端工程中组件间通信是一个核心难题。选择不当的通信方式会导致代码耦合度高、数据流难以追踪、调试困难。MoneyTrack 根据不同的通信场景有策略地使用了三种通信方案EventBus用于全局跨模块刷新如账单数据变更后刷新首页和统计页emitter用于同一个 feature 内的模块间通信如资产变更通知Prop 属性传递用于父子组件的直接数据传递。本章分析每种方案的优缺点和适用场景并提供选型决策树供开发者参考。核心知识点1. 三种通信方式的对比概览通信方式对比耦合度高类型安全数据流清晰耦合度中轻量级有明确实例耦合度低事件名需管理调试困难Prop/Link父子组件通信emitter模块内通信EventBus全局跨模块通信适用父子组件直接数据传递适用同一 feature服务与UI通信适用跨模块全局刷新通知2. 通信方案选型决策树在实际开发中可以按照以下决策树来选择通信方案是否是否是否是否父子组件直接传递Prop/Link类型安全首选是否同一模块内的服务和 UI 通信emitter鸿蒙原生API是否需要多模块广播通知EventBus全局事件考虑状态管理方案如 AppStorage/LocalStorage核心原则能用 Prop 解决的不用 emitter能用 emitter 解决的不用 EventBus——缩小影响范围让数据流清晰可控。3. EventBus全局刷新EventBus 采用发布-订阅模式适用于一对多的广播场景优点解耦彻底发送方不需要知道谁在监听非常适合跨 feature 的数据变更通知。缺点事件名需要全局唯一管理调试时难以追踪调用链。过度使用会导致事件风暴——大量全局事件在系统中无序传递数据流动失去可预测性。4. emitter模块内通信鸿蒙系统的emitterAPI 提供进程内的事件能力与 EventBus 的关键差异包括对比维度EventBusemitter实现方式自定义实现鸿蒙原生 API实例管理全局单例可创建多个实例性能开销略高自定义实现较低原生实现调试支持无DevEco Studio 支持推荐场景跨模块全局通知模块内服务与 UI 通信emitter 有明确的EventEmitter实例管理可以在模块内创建独立的 emitter 实例避免全局事件污染。例如 asset_feature 模块内部的资产变更通知使用独立的 emitter 实例不会与其他模块的事件名冲突。5. Prop 属性传递父子组件优点类型安全、数据流清晰、易于调试。缺点多层嵌套时传递繁琐props drilling此时可考虑使用 Provide/Consume 或 AppStorage。6. 过度使用全局事件的后果如果滥用 EventBus会导致以下问题调试困难无法追踪事件的发送源和消费链出现 Bug 时难以定位。性能下降全局事件触发时所有监听者都会执行回调即使回调中做了空判断函数调用本身仍有开销。内存泄漏注册了 EventBus 监听的组件在销毁时需要显式取消注册遗漏会导致内存泄漏和僵尸回调。可预测性降低全局事件使数据流动变得隐式新加入的开发者很难理解修改 A 数据后B、C、D 页面的哪部分会刷新。7. 通信性能考量不同通信方式的性能表现差异明显Prop 传递性能最优。数据变更触发最小粒度的组件更新ArkUI 框架会精确计算需要重新渲染的组件。emitter性能良好。原生实现的异步事件队列适合高频但小数据量的通信场景。EventBus自定义实现建议避免高频触发如每秒超过 10 次。对于高频更新的数据如计时器、实时行情优先使用 Prop 或 AppStorage。项目代码案例EventBus 全局刷新// 账单页面修改后发送全局刷新事件EventBus.emit(EventConstants.BILL_UPDATED);// 统计页面监听EventBus.on(EventConstants.BILL_UPDATED,(){this.refreshStatistics();});// 注意组件销毁时需要取消注册aboutToDisappear(){EventBus.off(EventConstants.BILL_UPDATED);}emitter 资产变更通信import{emitter}fromkit.ArkTS;// 资产变更通知emitter.emit({eventId:EventId.ASSET_CHANGED},{data:{assetId}});// 监听资产变更emitter.on({eventId:EventId.ASSET_CHANGED},(data){this.updateAssetInfo(data);});选择通信方案的核心原则是缩小影响范围让数据流清晰可控。在 MoneyTrack 中80% 的组件间通信使用 Prop 解决15% 使用 emitter只有不到 5% 的跨模块场景使用 EventBus。推荐参考文档组件通信最佳实践emitter API 参考Prop / Link / Event 装饰器文档