【HarmonyOS Next】跨模块交互的事件路由

  • 本文所有代码案例均基于Api12。

如果一个工程中,已经使用分模块开发,多个项目要耦合到一起,难免会遇到跨模块的方法调用。在业务层,仓库A直接调用仓库B,就构成了引用,想避免引用就需要一个中间库帮他们传递消息。

AB双方约定好消息路由,分实现、注册、调用,三步实现通信。

1、创建事件路由名和实现对象: 创建实现对象,在指定方法内实现路由方法

typescript 复制代码
// 路由地址,根据需要命名
let testRouter: CustomURL.Key = new CustomURL.Key("test_path")

// 路由方法实现对象,需要继承自CustomEventRouter.Protocol 
export class TestEventRouter implements CustomEventRouter.Protocol {

  registerRouter(navigator: CustomEventRouter.Navigator): void {

    navigator.handleEvent(testRouter, (params: Record<string, Object>) => {
      // xxxxxxx
      return undefined
    })

  }
}

2、注册: APP启动后将路由对象注册给事件路由

scss 复制代码
  // 不同模块下的实现对象可以分别注入
  CustomEventRouter.registerModule(new TestEventRouter(), new Test1EventRouter())
  CustomEventRouter.registerModule(new Test2EventRouter())

3、调用: 根据路由名调用方法并获取返回参数

javascript 复制代码
  // 根据实际需要接收返回值,如果没有设置返回值,可以不接收
  let result: Object = CustomEventRouter.open(testRouter)

这样一个事件路由就做好了。


事件路由的核心代码:

typescript 复制代码
/**
 * 路由地址的声明。起到代码约束功能
 */
export namespace CustomURL {
  /**
   * 路由地址的数据类型,约束业务模块调用规范
   */
  export class Key {
    // 真实的路由地址
    path: string

    constructor(path: string) {
      this.path = path
    }
  }
}

export namespace CustomEventRouter {

  /**
   * 调用打开路由
   * @param url 路由地址
   * @param paramter 参数
   * @returns 路由实现方法的回调
   */
  export function open(
    url: CustomURL.Key,
    paramter?: Object
  ): ESObject {
    if (baseNavigator.has(url.path)) {
      let objFunc: Function | undefined = baseNavigator.get(url.path)
      if (objFunc) {
        return objFunc(paramter)
      }
    }
  }

  /**
   * 注册路由实现对象的方法,每个模块需自己实现Protocol接口,app启动后在适当的时机调用该方法实现注册,如Index.ets文件
   * @param items 实现路由注册接口的对象
   */
  export function registerModule(...items: Protocol[]) {
    let navigator: Navigator = new Navigator()
    items.forEach((item: Protocol, index: number, array: Protocol[]) => {
      item.registerRouter(navigator)
    })
  }

  /**
   * 移除指定路由
   * @param items 要移除的路由URL
   */
  export function removeURL(...items: CustomURL.Key[]) {
    items.forEach((url: CustomURL.Key, index: number, array: CustomURL.Key[]) => {
      baseNavigator.delete(url.path)
    })
  }

  /**
   * 需要业务组件去实现的路由接口。用协议实现对其他模块方法的调用
   */
  export interface Protocol {
    /**
     * 在这个方法中注册路由
     * @param navigator 注册的规范对象
     */
    registerRouter(navigator: Navigator): void
  }

  /**
   * RouteNavigator是用来注册的model,对代码规范约束的功能。不对外直接暴露baseNavigator,是避免map类型被错误操作
   */
  export class Navigator {
    /**
     * 调用这个方法实现注册单条路由
     * @param key 路由地址
     * @param value 实现方法,Function跟系统用法相同
     */
    handleEvent(key: CustomURL.Key, value: Function) {
      baseNavigator[key.path] = value
    }
  }

  /**
   * 实际存储路由和方法的对象。因为是map,不对外部文件暴露,避免错误操作
   */
  const baseNavigator: Map<string, Function> = new Map()
}
  • 关于本文中使用到【ESObject】的说明: 在鸿蒙当前的版本中,已经不允许直接使用any类型操作对象,检查规则会报错。官方文档给了说明,他们统计过必须使用any的代码不到1%,如果特殊场景下,也给出了替代方案: declare type ESObject = any; 在本文中,因为需要和Function对齐传参,所以使用了替代方案声明参数。
相关推荐
坚果派·白晓明16 分钟前
在鸿蒙设备上快速验证由lycium工具快速交叉编译的C/C++三方库
c语言·c++·harmonyos·鸿蒙·编程语言·openharmony·三方库
lbb 小魔仙1 小时前
【HarmonyOS实战】OpenHarmony + RN:自定义 useFormik 表单处理
react native·harmonyos
果粒蹬i1 小时前
【HarmonyOS】DAY7:鸿蒙跨平台 Tab 开发问题与列表操作难点深度复盘
华为·harmonyos
王码码20351 小时前
Flutter for OpenHarmony 实战之基础组件:第二十七篇 BottomSheet — 动态底部弹窗与底部栏菜单
android·flutter·harmonyos
ITUnicorn2 小时前
【HarmonyOS6】ArkTS 自定义组件封装实战:动画水杯组件
华为·harmonyos·arkts·鸿蒙·harmonyos6
全栈探索者2 小时前
@Component + struct = 你的新函数组件——React 开发者的鸿蒙入门指南(第 2 期)
react·harmonyos·arkts·前端开发·deveco studio·鸿蒙next·函数组件
廖松洋(Alina)3 小时前
【收尾以及复盘】flutter开发鸿蒙APP之成就徽章页面
flutter·华为·开源·harmonyos·鸿蒙
廖松洋(Alina)4 小时前
【收尾以及复盘】flutter开发鸿蒙APP之打卡日历页面
flutter·华为·开源·harmonyos·鸿蒙
廖松洋(Alina)4 小时前
【收尾以及复盘】flutter开发鸿蒙APP之本月数据统计页面
flutter·华为·开源·harmonyos·鸿蒙
果粒蹬i4 小时前
【HarmonyOS】DAY8:React Native for OpenHarmony 实战:多端响应式布局与高可用交互设计
react native·交互·harmonyos