鸿蒙开发:事件订阅EventHub 原创

程序员一鸣
发布于 2025-3-31 21:38
1092浏览
0收藏

前言


本文基于Api13


有这样一个案例,页面A跳转到了页面B,页面B又跳转了页面C,在页面C中需要把数据回调至页面A,我们该如何去做?又或者,在一个模块中需要调用另一个模块中的方法,又该如何调用?在很多的场景下,我们都会想到回调的方式,如果层级较多呢?逐级回调能够解决,但是是十分的麻烦,为了解决这个问题,在鸿蒙当中提供了一个类似于EventBus的能力,它就是EventHub

一句话解读:EventHub是鸿蒙开发中用于线程内通信的事件中心模块提供了订阅、触发和取消订阅事件的能力。


主要的特点有三个,第一个就是事件中心,基于发布订阅模式,允许通过事件名进行通信,第二个就是仅支持同一线程内的事件传递,不适用于跨进程或虚拟机间的通信,第三个是单例模式,每个AbilityContext实例拥有独立的EventHub,事件操作仅作用于当前上下文


简单案例


@Entry
@Component
struct DemoPage {
  aboutToAppear(): void {
    getContext().eventHub.on("test", (data: string) => {
      //订阅指定事件
      console.log("====" + data)
    })
  }

  build() {
    Column() {
      Button("点击")
        .onClick(() => {
          //触发指定事件
          getContext().eventHub.emit("test", "hello")
        })
    }
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.


以上的代码,点击按钮之后,就是触发一个test事件,并发送一个hello字符串,在aboutToAppear声明周期中,订阅了test事件,就会接收到发送的消息。


鸿蒙开发:事件订阅EventHub-鸿蒙开发者社区


EventHub方法介绍


查看源码,EventHub中共有三个方法,分别是on,off和emit方法,源码如下:


on(event: string, callback: Function): void;
   
off(event: string, callback?: Function): void;
   
emit(event: string, ...args: Object[]): void;
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.

on方法

主要用于订阅指定事件。


参数名

类型

必填

说明

event

string

事件名称。

callback

Function

事件回调,事件触发后调用。

off方法

主要用于取消订阅指定事件,如果传入callback,代表着取消指定的callback对指定事件的订阅,当该事件触发后,将不会回调该callback;如果不传callback,代表着取消所有callback对指定事件的订阅。


参数名

类型

必填

说明

event

string

事件名称。

callback

Function

事件回调。如果不传callback,则取消订阅该事件下所有callback。


emit方法


用于触发指定事件。

参数名

类型

必填

说明

event

string

事件名称。

...args

Object[]

可变参数,事件触发时,传递给回调函数的参数。

组件之间数据传递

本身EventHub就三个方法,使用起来也是非常的简单,可以适用于页面或者组件之间的数据传递,或者状态回传,下面就简单的以组件之间的数据传递为案例,简单的演示一下。

@Entry
@Component
struct DemoPage {
  @State message: string = ""

  aboutToAppear(): void {
    getContext().eventHub.on("callBack", (data: string) => {
      //订阅事件,接收消息
      this.message = data
    })
  }

  aboutToDisappear(): void {
    //取消订阅
    getContext().eventHub.off("callBack")
  }

  build() {
    Column() {
      Text(this.message)
      TestView()
    }.width("100%")
    .height("100%")
    .justifyContent(FlexAlign.Center)
  }
}

@Component
struct TestView {
  @State num: number = 0

  build() {
    Button("传递数据")
      .onClick(() => {
        this.num++
        getContext().eventHub.emit("callBack", "传递一个数据:" + this.num)
      })
  }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.


如果你只是想发送一个通知,可以不带参数。


相关总结


EventHub主要提供了轻量级的线程内通信机制,适用于组件间数据同步、状态通知等场景,在实际的开发中,一定要注意两个事项,其一就是,注意off取消订阅的使用,可以避免内存泄漏,其二就是,关于事件命名的规范,建议使用常量定义事件名,避免硬编码错误。

©著作权归作者所有,如需转载,请注明出处,否则将追究法律责任
收藏
回复
举报


回复
    相关推荐