轻量级的本地事件发布/订阅(Pub/Sub)机制,用于同一个 Ability 内不同页面或组件之间的通信,实现解耦的组件间通信
eventHub是Ability 内部私有的,不能跨 Ability 通信(如从一个 EntryAbility 发消息到另一个 ServiceAbility)。
使用:
1:在 Ability 中获取 eventHub(你的代码)
// EntryAbility.ts export default class EntryAbility extends UIAbility { onCreate() { // 获取 eventHub(通常保存为成员变量) this.eventHub = this.context.eventHub; } }this.context.eventHub只能在UIAbility的生命周期方法中访问(如onCreate,onWindowStageCreate)。
2:在页面中使用(需通过 AppStorage 或其他方式传递)
由于 ArkTS 页面组件(@Component)无法直接访问Ability的context,通常需要将eventHub存入全局状态:
在 Ability 中存入 AppStorage:
// EntryAbility.ts import { AppStorage } from '@kit.ArkUI'; export default class EntryAbility extends UIAbility { onWindowStageCreate(windowStage: window.WindowStage) { // 将 eventHub 存入全局(注意:仅存引用,不序列化) AppStorage.setOrCreate('eventHub', this.context.eventHub); windowStage.loadContent('pages/Index'); } }在页面中使用:
// Index.ets import { AppStorage } from '@kit.ArkUI'; @Entry @Component struct Index { build() { Column() { Button('发送事件') .onClick(() => { const hub = AppStorage.get<EventHub>('eventHub'); // 发布事件 hub.emit('userLogin', { userId: '123', name: 'Alice' }); }) } } }在另一个页面监听:
// Profile.ets @Entry @Component struct Profile { aboutToAppear() { const hub = AppStorage.get<EventHub>('eventHub'); // 订阅事件 hub.on('userLogin', (data) => { console.log('收到登录事件:', data); // 更新 UI }); } aboutToDisappear() { // 务必取消订阅,避免内存泄漏! const hub = AppStorage.get<EventHub>('eventHub'); hub.off('userLogin'); } }方法 | 说明 |
|---|---|
| 发布事件(可传参数) |
| 订阅事件 |
| 取消订阅(建议在 |
| 订阅一次(触发后自动取消) |
3:注意事项
1.不能跨 Ability 使用
eventHub仅限同一个 UIAbility 内部通信。跨 Ability 请使用Want / AbilityStage / 全局状态管理(如 AppStorage + 状态变量)。
2.必须手动取消订阅
否则会导致内存泄漏(回调函数持有页面引用,阻止 GC)。
推荐在
aboutToDisappear()中调用off()。
3.不适合复杂状态管理
对于全局状态(如用户信息、主题),建议使用:
@StorageLink+AppStorage自定义状态管理库(如类似 Redux 的方案)
4:替代方案对比
| 方案 | 适用场景 | 优点 | 缺点 |
|---|---|---|---|
eventHub | 同 Ability 内简单通知 | 轻量、官方支持 | 不能跨 Ability,需手动管理订阅 |
AppStorage+@StorageLink | 全局状态共享 | 响应式更新,自动同步 | 仅支持简单数据类型 |
| 自定义 Callback | 父子组件通信 | 简单直接 | 需 props 逐层传递 |
UIContext封装 | 统一事件管理 | 可扩展 | 非官方,增加复杂度 |