📖 前言

HMRouter 是鸿蒙应用开发中功能强大的路由框架,提供了路由拦截、页面生命周期、自定义转场动画等丰富功能。但在实际项目中,直接使用 HMRouterMgr 可能存在以下问题:

  1. 类型不统一:框架使用 ESObject,项目可能更倾向于使用 Object
  2. 参数复杂HMRouterPathInfo 对象构建繁琐,需要手动组装多个可选参数
  3. 代码重复:每次跳转都需要构建完整的路径信息对象
  4. 维护困难:如果框架升级,需要修改大量业务代码

因此,我们需要对 HMRouter 进行封装,提供更简洁、统一的 API,同时保持与框架的兼容性。

HMRouter的路由核心API主要存在于HMRouterMgr.ets中,如下:

import { collections } from '@kit.ArkTS';
import { HMInterceptorInstance, HMLifecycleInstance, HMPageInstance } from '../store/ComponentInstance';
import { HMRouterPathCallback } from './HMRouterPathCallback';
import { HMRouterPathInfo } from './HMRouterPathInfo';
import { IHMAnimator } from './IHMAnimator';
import { HMRouterConfig } from './HMRouterConfig';
import { HMPageLifecycle } from '../lifecycle/HMPageLifecycle';
import { IHMLifecycleOwner } from '../lifecycle/interface/IHMLifecycleOwner';
import { HMServiceResp } from './IHMService';
import { HMPageParam, HMParamType } from './HMParamType';
import { IHMRouterBuilder } from './IHMRouterBuilder';
import { RouterItem } from '../store/entity/BundleInfo';
import { HMUriInterceptor } from '../interceptor/HMUriInterceptor';
import { AbilityConstant, Want } from '@kit.AbilityKit';
import { RemoveCallback, RemoveListenerOptions } from '../removeservice/RemoveManager';
export declare class HMRouterMgr {
    static isInit: boolean;
    private static service;
    private static routerStore;
    private static pageLifecycleMgr;
    private static config;
    static sdkApiVersion: number;
    /**
     * Initialize HMRouter
     * @Param config
     */
    static init(config: HMRouterConfig): Promise<collections.Array<RouterItem>>;
    /**
     * Enable HMRouter logs
     * @param level
     */
    static openLog(level: 'DEBUG' | 'INFO'): void;
    /**
     * Push to target page
     * @param pathInfo
     * @param callback
     */
    static push(pathInfo: HMRouterPathInfo, callback?: HMRouterPathCallback): void;
    /**
     * Replace current page to target page
     * @param pathInfo
     * @param callback
     */
    static replace(pathInfo: HMRouterPathInfo, callback?: HMRouterPathCallback): void;
    /**
     * Back to target page
     * @param pathInfo
     * @param skipedLayerNumber
     * The number of levels returned by the page, default to 0, indicates returning to the previous level,
     * 1 indicates skipping one level of page return, two pages are pushed out at the same time,
     * and the pathInfo.pathInfo parameter has higher priority than skipedLayerNumber
     */
    static pop(pathInfo?: HMRouterPathInfo, skipedLayerNumber?: number): void;
    /**
     * Push to target page with async interceptor support
     * @param pathInfo
     * @param callback
     */
    static pushAsync(pathInfo: HMRouterPathInfo, callback?: HMRouterPathCallback): Promise<void>;
    /**
     * Replace current page to target page with async interceptor support
     * @param pathInfo
     * @param callback
     */
    static replaceAsync(pathInfo: HMRouterPathInfo, callback?: HMRouterPathCallback): Promise<void>;
    /**
     * Back to target page with async interceptor support
     * @param pathInfo
     * @param skipedLayerNumber
     * The number of levels returned by the page, default to 0, indicates returning to the previous level,
     * 1 indicates skipping one level of page return, two pages are pushed out at the same time,
     * and the pathInfo.pathInfo parameter has higher priority than skipedLayerNumber
     */
    static popAsync(pathInfo?: HMRouterPathInfo, skipedLayerNumber?: number): Promise<void>;
    /**
     * Get pathStack by navigationId
     * @param navigationId
     * @returns
     */
    static getPathStack(navigationId: string): NavPathStack | null;
    /**
     * Get current page params
     * @returns
     */
    static getCurrentParam(type?: HMParamType): HMPageParam | Map<string, Object> | Object | RegExpExecArray | null;
    /**
     * Get page parameters for specific component instance
     * @param component Component instance
     * @param type Parameter type
     * @returns
     */
    static getCurrentParam(component?: CustomComponent, type?: HMParamType): HMPageParam | Map<string, Object> | Object | RegExpExecArray | null;
    /**
     * Get the current page lifecycle management instance
     *
     * which can be used to retrieve the data content initialized during lifecycle stages
     * @returns
     */
    static getCurrentLifecycleOwner(): IHMLifecycleOwner | null;
    /**
     * Register global interceptor
     * @param interceptorInstance
     * @returns
     */
    static registerGlobalInterceptor(interceptorInstance: HMInterceptorInstance): void;
    /**
     * Unregister global interceptor
     * @param interceptorName
     * @returns
     */
    static unRegisterGlobalInterceptor(interceptorName: string): boolean;
    /**
     * Register global lifecycle
     * @param lifecycleInstance
     * @returns
     */
    static registerGlobalLifecycle(lifecycleInstance: HMLifecycleInstance): void;
    /**
     * Unregister global lifecycle
     * @param lifecycleName
     * @returns
     */
    static unRegisterGlobalLifecycle(lifecycleName: string): boolean;
    /**
     * Register global animator
     * @param key
     * @param animator
     */
    static registerGlobalAnimator(navigationId: string, key: 'standard' | 'dialog', animator: IHMAnimator): void;
    /**
     * Unregister global animator
     * @param key
     * @returns
     */
    static unRegisterGlobalAnimator(navigationId: string, key: 'standard' | 'dialog'): boolean;
    /**
     * Register custom dynamic router
     * @param pageInstance
     */
    static registerPageBuilder(pageInstance: HMPageInstance): boolean;
    /**
     * Generate page lifecycle management instance
     * @returns Unique identifier for page lifecycle instance
     */
    static generatePageLifecycleId(): string;
    /**
     * get page lifecycle by id
     * @param pageLifecycleId
     * @returns page lifecycle instance
     */
    static getPageLifecycleById(pageLifecycleId: string): HMPageLifecycle | undefined;
    /**
     * Execute service
     * @param serviceName
     * @param args
     * @returns service response
     */
    static request(serviceName: string, ...args: Object[]): HMServiceResp;
    /**
     * get service
     * @param serviceName
     * @returns serviceInstance
     */
    static getService<T>(serviceName: string, ...args: Object[]): T | undefined;
    /**
     * getPageBuilderByUrl
     * @param url
     * @returns WrappedBuilder
     */
    static getPageBuilderByUrl(url: string): WrappedBuilder<Object[]> | undefined;
    /**
     * to
     * @param url
     * @returns WrappedBuilder
     */
    static to(pageUrl?: string): IHMRouterBuilder;
    /**
     * 设置返回参数
     * @param pageUrl
     * @returns
     */
    static setPopParam(param: Object): void;
    /**
     * 同步import,napi_load_module_with_info提供的ArkTS层接口
     * @param modulePath eg: "entry/src/main/ets/Test"
     * @param moduleInfo eg: "com.example.application/entry"
     * @returns
     */
    static loadModule(modulePath: string, moduleInfo: string): ESObject;
    /**
     * Get pathStack by navigationId
     * @param navigationId
     * @returns
     */
    static getCurrentPathStack(): NavPathStack | null;
    static removeAll(animated?: boolean): void;
    /**
     * 判断url类型
     * @param pageUrl
     */
    static existUrl(url: string): boolean;
    static isService(url: string): boolean;
    static requestWithCallback(serviceName: string, callback: Callback<HMServiceResp, void>, ...args: Object[]): void;
    /**
     * 返回并跳过所有弹窗页面
     * @param pathInfo
     * @returns
     */
    static popSkipDialog(pathInfo?: HMRouterPathInfo): void;
    /**
     * 处理外部传入URI
     * @param want Want对象,包含URI信息
     * @param interceptor URI拦截器实例
     * @returns 是否成功处理
     */
    static handleUri(want: Want, interceptor: HMUriInterceptor, launchParam?: AbilityConstant.LaunchParam): boolean;
    /**
     * removeBy方法的操作监听
     * @param callback callback监听器回调,返回删除页面信息
     * @param options options设置监听导航容器ID
     * @returns 是否成功处理
     */
    static addRemoveListener(callback: RemoveCallback, options?: RemoveListenerOptions): void;
    static deleteRemoveListener(callback: RemoveCallback): void;
    static clearRemoveListener(): void;
    /**
     * 设置默认navigationId
     * @param navigationId
     */
    static setDefaultNavigationId(navigationId: string): void;
    static clearDefaultNavigationId(): void;
}

本人基于HMRouterMgr封装的HMRouterUtil工具类,如下:

import { HMRouterUtilMgr } from '../HMRouterUtilMgr';
import {
  HMRouterUtilAnimator,
  HMRouterUtilLifecycleOwner,
  HMRouterUtilPageParam,
  HMRouterUtilParamType,
  HMRouterUtilPathCallback,
  HMRouterUtilPathInfo,
  HMRouterUtilOptions,
  HMRouterUtilServiceResp,
  HMRouterUtilUriInterceptor
} from '../model/Index';
import { collections } from '@kit.ArkTS';
import { AbilityConstant, Want } from '@kit.AbilityKit';
import { HMRouterConfig } from '@hadss/hmrouter/src/main/ets/api/HMRouterConfig';
import { RouterItem } from '@hadss/hmrouter/src/main/ets/store/entity/BundleInfo';
import {
  HMInterceptorInstance,
  HMLifecycleInstance,
  HMPageInstance
} from '@hadss/hmrouter/src/main/ets/store/ComponentInstance';
import { HMPageLifecycle } from '@hadss/hmrouter/src/main/ets/lifecycle/HMPageLifecycle';
import { RemoveCallback, RemoveListenerOptions } from '@hadss/hmrouter/src/main/ets/removeservice/RemoveManager';
import { IHMRouterBuilder } from '@hadss/hmrouter/src/main/ets/api/IHMRouterBuilder';


/**
 * HMRouter 路由工具类
 * 提供简化的路由操作方法
 */
export class HMRouterUtil {
  /**
   * 构建路由路径信息对象
   * @param pageUrl 目标页面URL
   * @param param 传递的参数
   * @param options 路由选项
   * @returns 路由路径信息对象
   */
  private static buildPathInfo(
    pageUrl?: string,
    param?: Object,
    options?: HMRouterUtilOptions
  ): HMRouterUtilPathInfo {
    const pathInfo: HMRouterUtilPathInfo = {};
    if (pageUrl !== undefined) {
      pathInfo.pageUrl = pageUrl;
    }
    if (param !== undefined) {
      pathInfo.param = param;
    }
    if (options) {
      if (options.navigationId !== undefined) {
        pathInfo.navigationId = options.navigationId;
      }
      if (options.interceptors !== undefined) {
        pathInfo.interceptors = options.interceptors;
      }
      if (options.lifecycle !== undefined) {
        pathInfo.lifecycle = options.lifecycle;
      }
      if (options.animator !== undefined) {
        pathInfo.animator = options.animator;
      }
      if (options.skipAllInterceptor !== undefined) {
        pathInfo.skipAllInterceptor = options.skipAllInterceptor;
      }
    }
    return pathInfo;
  }

  /**
   * 跳转到指定页面(同步)
   * @param pageUrl 目标页面URL
   * @param param 传递的参数(可选)
   * @param options 路由选项(可选)
   * @param callback 路由回调(可选)
   */
  static push(pageUrl: string, param?: Object, options?: HMRouterUtilOptions,
    callback?: HMRouterUtilPathCallback): void {
    const pathInfo: HMRouterUtilPathInfo = HMRouterUtil.buildPathInfo(pageUrl, param, options);
    HMRouterUtilMgr.push(pathInfo, callback);
  }

  /**
   * 跳转到指定页面(异步,支持异步拦截器)
   * @param pageUrl 目标页面URL
   * @param param 传递的参数(可选)
   * @param options 路由选项(可选)
   * @param callback 路由回调(可选)
   */
  static async pushAsync(pageUrl: string, param?: Object, options?: HMRouterUtilOptions,
    callback?: HMRouterUtilPathCallback): Promise<void> {
    const pathInfo: HMRouterUtilPathInfo = HMRouterUtil.buildPathInfo(pageUrl, param, options);
    await HMRouterUtilMgr.pushAsync(pathInfo, callback);
  }

  /**
   * 替换当前页面(同步)
   * @param pageUrl 目标页面URL
   * @param param 传递的参数(可选)
   * @param options 路由选项(可选)
   * @param callback 路由回调(可选)
   */
  static replace(pageUrl: string, param?: Object, options?: HMRouterUtilOptions,
    callback?: HMRouterUtilPathCallback): void {
    const pathInfo: HMRouterUtilPathInfo = HMRouterUtil.buildPathInfo(pageUrl, param, options);
    HMRouterUtilMgr.replace(pathInfo, callback);
  }

  /**
   * 替换当前页面(异步,支持异步拦截器)
   * @param pageUrl 目标页面URL
   * @param param 传递的参数(可选)
   * @param options 路由选项(可选)
   * @param callback 路由回调(可选)
   */
  static async replaceAsync(pageUrl: string, param?: Object, options?: HMRouterUtilOptions,
    callback?: HMRouterUtilPathCallback): Promise<void> {
    const pathInfo: HMRouterUtilPathInfo = HMRouterUtil.buildPathInfo(pageUrl, param, options);
    await HMRouterUtilMgr.replaceAsync(pathInfo, callback);
  }

  /**
   * 返回上一页(同步)
   * @param pageUrl 目标页面URL(可选,指定返回到某个页面)
   * @param skipedLayerNumber 跳过的页面层数(可选,默认返回上一页)
   * @param param 返回参数(可选)
   * @param options 路由选项(可选)
   */
  static pop(pageUrl?: string, skipedLayerNumber?: number, param?: Object, options?: HMRouterUtilOptions): void {
    const pathInfo: HMRouterUtilPathInfo | undefined = pageUrl || param !== undefined || options
      ? HMRouterUtil.buildPathInfo(pageUrl, param, options)
      : undefined;
    HMRouterUtilMgr.pop(pathInfo, skipedLayerNumber);
  }

  /**
   * 返回上一页(异步,支持异步拦截器)
   * @param pageUrl 目标页面URL(可选,指定返回到某个页面)
   * @param skipedLayerNumber 跳过的页面层数(可选,默认返回上一页)
   * @param param 返回参数(可选)
   * @param options 路由选项(可选)
   */
  static async popAsync(pageUrl?: string, skipedLayerNumber?: number, param?: Object,
    options?: HMRouterUtilOptions): Promise<void> {
    const pathInfo: HMRouterUtilPathInfo | undefined = pageUrl || param !== undefined || options
      ? HMRouterUtil.buildPathInfo(pageUrl, param, options)
      : undefined;
    await HMRouterUtilMgr.popAsync(pathInfo, skipedLayerNumber);
  }

  /**
   * 返回并跳过所有弹窗页面
   * @param pageUrl 目标页面URL(可选)
   * @param param 返回参数(可选)
   * @param options 路由选项(可选)
   */
  static popSkipDialog(pageUrl?: string, param?: Object, options?: HMRouterUtilOptions): void {
    const pathInfo: HMRouterUtilPathInfo | undefined = pageUrl || param !== undefined || options
      ? HMRouterUtil.buildPathInfo(pageUrl, param, options)
      : undefined;
    HMRouterUtilMgr.popSkipDialog(pathInfo);
  }

  /**
   * 获取当前页面参数
   * @param type 参数类型(可选)
   * @returns 页面参数
   */
  static getCurrentParam(type?: HMRouterUtilParamType): HMRouterUtilPageParam | Map<string, Object> | Object | RegExpExecArray | null;

  /**
   * 获取指定组件实例的页面参数
   * @param component 组件实例(可选)
   * @param type 参数类型(可选)
   * @returns 页面参数
   */
  static getCurrentParam(component?: CustomComponent,
    type?: HMRouterUtilParamType): HMRouterUtilPageParam | Map<string, Object> | Object | RegExpExecArray | null;

  /**
   * 获取当前页面参数(实现)
   * @param componentOrType 组件实例或参数类型
   * @param maybeType 参数类型(可选)
   * @returns 页面参数
   */
  static getCurrentParam(componentOrType?: CustomComponent | HMRouterUtilParamType,
    maybeType?: HMRouterUtilParamType): HMRouterUtilPageParam | Map<string, Object> | Object | RegExpExecArray | null {
    if (typeof componentOrType === 'number') {
      return HMRouterUtilMgr.getCurrentParam(componentOrType);
    } else {
      return HMRouterUtilMgr.getCurrentParam(componentOrType as CustomComponent, maybeType);
    }
  }

  /**
   * 获取路由栈
   * @param navigationId 导航容器ID
   * @returns 路由栈
   */
  static getPathStack(navigationId: string): NavPathStack | null {
    return HMRouterUtilMgr.getPathStack(navigationId);
  }

  /**
   * 设置返回参数
   * @param param 返回参数
   */
  static setPopParam(param: Object): void {
    HMRouterUtilMgr.setPopParam(param);
  }

  /**
   * 检查路由是否已初始化
   * @returns 是否已初始化
   */
  static isInit(): boolean {
    return HMRouterUtilMgr.isInit;
  }

  /**
   * 检查页面URL是否存在
   * @param pageUrl 页面URL
   * @returns 是否存在
   */
  static existUrl(pageUrl: string): boolean {
    return HMRouterUtilMgr.existUrl(pageUrl);
  }

  /**
   * 使用链式调用方式跳转(推荐使用)
   * @param pageUrl 目标页面URL(可选)
   * @returns 路由构建器
   */
  static to(pageUrl?: string): IHMRouterBuilder {
    return HMRouterUtilMgr.to(pageUrl);
  }

  /**
   * 初始化 HMRouter
   * @param config 路由配置
   * @returns 路由项数组
   */
  static init(config: HMRouterConfig): Promise<collections.Array<RouterItem>> {
    return HMRouterUtilMgr.init(config);
  }

  /**
   * 启用 HMRouter 日志
   * @param level 日志级别
   */
  static openLog(level: 'DEBUG' | 'INFO'): void {
    HMRouterUtilMgr.openLog(level);
  }

  /**
   * 获取当前页面生命周期管理实例
   * @returns 生命周期管理实例
   */
  static getCurrentLifecycleOwner(): HMRouterUtilLifecycleOwner | null {
    return HMRouterUtilMgr.getCurrentLifecycleOwner();
  }

  /**
   * 注册全局拦截器
   * @param interceptorInstance 拦截器实例
   */
  static registerGlobalInterceptor(interceptorInstance: HMInterceptorInstance): void {
    HMRouterUtilMgr.registerGlobalInterceptor(interceptorInstance);
  }

  /**
   * 注销全局拦截器
   * @param interceptorName 拦截器名称
   * @returns 是否成功
   */
  static unRegisterGlobalInterceptor(interceptorName: string): boolean {
    return HMRouterUtilMgr.unRegisterGlobalInterceptor(interceptorName);
  }

  /**
   * 注册全局生命周期
   * @param lifecycleInstance 生命周期实例
   */
  static registerGlobalLifecycle(lifecycleInstance: HMLifecycleInstance): void {
    HMRouterUtilMgr.registerGlobalLifecycle(lifecycleInstance);
  }

  /**
   * 注销全局生命周期
   * @param lifecycleName 生命周期名称
   * @returns 是否成功
   */
  static unRegisterGlobalLifecycle(lifecycleName: string): boolean {
    return HMRouterUtilMgr.unRegisterGlobalLifecycle(lifecycleName);
  }

  /**
   * 注册全局动画
   * @param navigationId 导航容器ID
   * @param key 动画键('standard' | 'dialog')
   * @param animator 动画实例
   */
  static registerGlobalAnimator(navigationId: string, key: 'standard' | 'dialog',
    animator: HMRouterUtilAnimator): void {
    HMRouterUtilMgr.registerGlobalAnimator(navigationId, key, animator);
  }

  /**
   * 注销全局动画
   * @param navigationId 导航容器ID
   * @param key 动画键('standard' | 'dialog')
   * @returns 是否成功
   */
  static unRegisterGlobalAnimator(navigationId: string, key: 'standard' | 'dialog'): boolean {
    return HMRouterUtilMgr.unRegisterGlobalAnimator(navigationId, key);
  }

  /**
   * 注册自定义动态路由
   * @param pageInstance 页面实例
   * @returns 是否成功
   */
  static registerPageBuilder(pageInstance: HMPageInstance): boolean {
    return HMRouterUtilMgr.registerPageBuilder(pageInstance);
  }

  /**
   * 生成页面生命周期管理实例ID
   * @returns 生命周期实例ID
   */
  static generatePageLifecycleId(): string {
    return HMRouterUtilMgr.generatePageLifecycleId();
  }

  /**
   * 根据ID获取页面生命周期
   * @param pageLifecycleId 生命周期ID
   * @returns 页面生命周期实例
   */
  static getPageLifecycleById(pageLifecycleId: string): HMPageLifecycle | undefined {
    return HMRouterUtilMgr.getPageLifecycleById(pageLifecycleId);
  }

  /**
   * 执行服务
   * @param serviceName 服务名称
   * @param args 参数
   * @returns 服务响应
   */
  static request(serviceName: string, ...args: Object[]): HMRouterUtilServiceResp {
    return HMRouterUtilMgr.request(serviceName, ...args);
  }

  /**
   * 获取服务实例
   * @param serviceName 服务名称
   * @param args 参数
   * @returns 服务实例
   */
  static getService<T>(serviceName: string, ...args: Object[]): T | undefined {
    return HMRouterUtilMgr.getService<T>(serviceName, ...args);
  }

  /**
   * 根据URL获取页面构建器
   * @param url 页面URL
   * @returns 页面构建器
   */
  static getPageBuilderByUrl(url: string): WrappedBuilder<Object[]> | undefined {
    return HMRouterUtilMgr.getPageBuilderByUrl(url);
  }

  /**
   * 同步导入模块
   * @param modulePath 模块路径,例如:"entry/src/main/ets/Test"
   * @param moduleInfo 模块信息,例如:"com.example.application/entry"
   * @returns 模块对象
   */
  static loadModule(modulePath: string, moduleInfo: string): Object {
    return HMRouterUtilMgr.loadModule(modulePath, moduleInfo);
  }

  /**
   * 获取当前路由栈
   * @returns 路由栈
   */
  static getCurrentPathStack(): NavPathStack | null {
    return HMRouterUtilMgr.getCurrentPathStack();
  }

  /**
   * 移除所有页面
   * @param animated 是否使用动画(可选)
   */
  static removeAll(animated?: boolean): void {
    HMRouterUtilMgr.removeAll(animated);
  }

  /**
   * 判断URL是否为服务
   * @param url URL
   * @returns 是否为服务
   */
  static isService(url: string): boolean {
    return HMRouterUtilMgr.isService(url);
  }

  /**
   * 使用回调执行服务
   * @param serviceName 服务名称
   * @param callback 回调函数
   * @param args 参数
   */
  static requestWithCallback(serviceName: string, callback: Callback<HMRouterUtilServiceResp, void>,
    ...args: Object[]): void {
    HMRouterUtilMgr.requestWithCallback(serviceName, callback, ...args);
  }

  /**
   * 处理外部传入URI
   * @param want Want对象,包含URI信息
   * @param interceptor URI拦截器实例
   * @param launchParam 启动参数(可选)
   * @returns 是否成功处理
   */
  static handleUri(want: Want, interceptor: HMRouterUtilUriInterceptor,
    launchParam?: AbilityConstant.LaunchParam): boolean {
    return HMRouterUtilMgr.handleUri(want, interceptor, launchParam);
  }

  /**
   * 添加移除监听器
   * @param callback 回调函数,返回删除页面信息
   * @param options 监听选项(可选)
   */
  static addRemoveListener(callback: RemoveCallback, options?: RemoveListenerOptions): void {
    HMRouterUtilMgr.addRemoveListener(callback, options);
  }

  /**
   * 删除移除监听器
   * @param callback 回调函数
   */
  static deleteRemoveListener(callback: RemoveCallback): void {
    HMRouterUtilMgr.deleteRemoveListener(callback);
  }

  /**
   * 清除所有移除监听器
   */
  static clearRemoveListener(): void {
    HMRouterUtilMgr.clearRemoveListener();
  }

  /**
   * 设置默认导航容器ID
   * @param navigationId 导航容器ID
   */
  static setDefaultNavigationId(navigationId: string): void {
    HMRouterUtilMgr.setDefaultNavigationId(navigationId);
  }

  /**
   * 清除默认导航容器ID
   */
  static clearDefaultNavigationId(): void {
    HMRouterUtilMgr.clearDefaultNavigationId();
  }

  /**
   * SDK API 版本号
   */
  static get sdkApiVersion(): number {
    return HMRouterUtilMgr.sdkApiVersion;
  }
}

后续会完善封装教程,像路由service、interceptor也是需要封装的,会陆续开源工程代码,敬请期待!


🎯 封装目标

  • 简化使用:提供更直观的 API,减少样板代码
  • 类型统一:统一使用 Object 类型,保持项目代码风格一致
  • 易于维护:封装层隔离框架变更,便于后续升级
  • 完整覆盖:封装 HMRouterMgr 中的所有方法,保持功能完整性

📁 项目结构

entry/src/main/ets/hmRouter/
├── model/                              # 类型定义目录
│   ├── Index.ets                       # 统一导出入口
│   ├── HMRouterUtilPathInfo.ets       # 路由路径信息类型别名
│   ├── HMRouterUtilPathCallback.ets   # 路由回调类型别名
│   ├── HMRouterUtilPageParam.ets      # 页面参数类型别名
│   ├── HMRouterUtilPopInfo.ets        # 页面返回信息类型别名
│   ├── HMRouterUtilParamType.ets      # 参数类型枚举导出
│   ├── HMRouterUtilInterceptor.ets    # 拦截器类型别名
│   ├── HMRouterUtilLifecycle.ets      # 生命周期类型别名
│   ├── HMRouterUtilAnimator.ets       # 动画类型别名
│   ├── HMRouterUtilOptions.ets        # 路由选项接口
│   ├── HMRouterUtilLifecycleOwner.ets # 生命周期所有者类型别名
│   ├── HMRouterUtilServiceResp.ets    # 服务响应类型别名
│   └── HMRouterUtilUriInterceptor.ets # URI拦截器类型别名
├── util/                               # 工具类目录
│   └── HMRouterUtil.ets                # 路由工具类(核心封装)
└── HMRouterUtilMgr.ets                 # 路由管理器类型别名

🚀 封装步骤

步骤 1:封装类型定义

首先,我们需要封装 HMRouter 的核心类型,统一项目内部使用。

1.1 创建类型别名文件

model/ 目录下创建类型别名文件,例如 HMRouterUtilPathInfo.ets

import { HMRouterPathInfo } from '@hadss/hmrouter';

/**
 * HMRouter 路由路径信息类型别名
 * 用于项目内部统一使用,包含路由跳转所需的所有信息
 */
export type HMRouterUtilPathInfo = HMRouterPathInfo;
1.2 封装核心类型

我们封装了以下 12 个核心类型:

类型别名

原始类型

说明

HMRouterUtilPathInfo

HMRouterPathInfo

路由路径信息

HMRouterUtilPathCallback

HMRouterPathCallback

路由回调

HMRouterUtilPageParam

HMPageParam

页面参数

HMRouterUtilPopInfo

HMPopInfo

页面返回信息

HMRouterUtilParamType

HMParamType

参数类型枚举

HMRouterUtilInterceptor

IHMInterceptor

拦截器接口

HMRouterUtilLifecycle

IHMLifecycle

生命周期接口

HMRouterUtilAnimator

IHMAnimator

动画接口

HMRouterUtilOptions

自定义接口

路由选项接口

HMRouterUtilLifecycleOwner

IHMLifecycleOwner

生命周期所有者

HMRouterUtilServiceResp

HMServiceResp

服务响应类型

HMRouterUtilUriInterceptor

HMUriInterceptor

URI拦截器

1.3 统一导出

model/Index.ets 中统一导出所有类型:

/**
 * HMRouter 类型定义统一导出
 * 导出 model 目录下的所有类型别名
 */

export { HMRouterUtilPathInfo } from './HMRouterUtilPathInfo';
export { HMRouterUtilPathCallback } from './HMRouterUtilPathCallback';
export { HMRouterUtilPageParam } from './HMRouterUtilPageParam';
export { HMRouterUtilPopInfo } from './HMRouterUtilPopInfo';
export { HMRouterUtilParamType } from './HMRouterUtilParamType';
export { HMRouterUtilInterceptor } from './HMRouterUtilInterceptor';
export { HMRouterUtilLifecycle } from './HMRouterUtilLifecycle';
export { HMRouterUtilAnimator } from './HMRouterUtilAnimator';
export { HMRouterUtilOptions } from './HMRouterUtilOptions';
export { HMRouterUtilLifecycleOwner } from './HMRouterUtilLifecycleOwner';
export { HMRouterUtilServiceResp } from './HMRouterUtilServiceResp';
export { HMRouterUtilUriInterceptor } from './HMRouterUtilUriInterceptor';

步骤 2:创建路由选项接口

为了简化参数传递,我们创建了 HMRouterUtilOptions 接口,将不常用的参数统一管理:

import {
  HMRouterUtilAnimator,
  HMRouterUtilInterceptor,
  HMRouterUtilLifecycle
} from './Index';

/**
 * HMRouter 路由选项接口
 * 用于统一传递路由参数(不包含 param 和 callback,这两个作为独立参数)
 */
export interface HMRouterUtilOptions {
  /** 导航容器ID */
  navigationId?: string;

  /** 自定义拦截器 */
  interceptors?: HMRouterUtilInterceptor[];

  /** 自定义生命周期 */
  lifecycle?: HMRouterUtilLifecycle;

  /** 自定义动画 */
  animator?: HMRouterUtilAnimator | boolean;

  /** 是否跳过所有拦截器 */
  skipAllInterceptor?: boolean;
}

设计思路

  • paramcallback 作为独立参数,因为使用频率高
  • 其他参数(navigationIdinterceptors 等)放在 options 对象中,减少参数数量

步骤 3:创建 HMRouterUtil 工具类

这是封装的核心,提供简化的路由 API。

3.1 核心设计
import { HMRouterUtilMgr } from '../HMRouterUtilMgr';
import {
  HMRouterUtilPathInfo,
  HMRouterUtilPathCallback,
  HMRouterUtilOptions
} from '../model/Index';

export class HMRouterUtil {
  /**
   * 构建路由路径信息对象(私有方法)
   */
  private static buildPathInfo(
    pageUrl?: string,
    param?: Object,
    options?: HMRouterUtilOptions
  ): HMRouterUtilPathInfo {
    const pathInfo: HMRouterUtilPathInfo = {};
    if (pageUrl !== undefined) {
      pathInfo.pageUrl = pageUrl;
    }
    if (param !== undefined) {
      pathInfo.param = param;
    }
    if (options) {
      if (options.navigationId !== undefined) {
        pathInfo.navigationId = options.navigationId;
      }
      if (options.interceptors !== undefined) {
        pathInfo.interceptors = options.interceptors;
      }
      if (options.lifecycle !== undefined) {
        pathInfo.lifecycle = options.lifecycle;
      }
      if (options.animator !== undefined) {
        pathInfo.animator = options.animator;
      }
      if (options.skipAllInterceptor !== undefined) {
        pathInfo.skipAllInterceptor = options.skipAllInterceptor;
      }
    }
    return pathInfo;
  }

  /**
   * 跳转到指定页面(同步)
   */
  static push(
    pageUrl: string,
    param?: Object,
    options?: HMRouterUtilOptions,
    callback?: HMRouterUtilPathCallback
  ): void {
    const pathInfo = HMRouterUtil.buildPathInfo(pageUrl, param, options);
    HMRouterUtilMgr.push(pathInfo, callback);
  }

  /**
   * 跳转到指定页面(异步)
   */
  static async pushAsync(
    pageUrl: string,
    param?: Object,
    options?: HMRouterUtilOptions,
    callback?: HMRouterUtilPathCallback
  ): Promise<void> {
    const pathInfo = HMRouterUtil.buildPathInfo(pageUrl, param, options);
    await HMRouterUtilMgr.pushAsync(pathInfo, callback);
  }

  // ... 其他方法
}
3.2 关键设计点
  1. 参数统一使用 Object:所有 ESObject 统一替换为 Object
  2. 常用参数独立paramcallback 作为独立参数,使用更方便
  3. 条件构建对象:使用 if 判断构建 pathInfo,避免 ArkTS 不支持展开运算符的问题
  4. 完整封装:封装 HMRouterMgr 中的所有 40+ 个方法

步骤 4:创建 HMRouterUtilMgr 类型别名

为了统一项目内部使用,我们创建了类型别名:

import { HMRouterMgr } from '@hadss/hmrouter';

/**
 * HMRouter 管理器类型别名
 * 直接使用 HMRouterMgr,不进行对象导出
 */
export { HMRouterMgr as HMRouterUtilMgr };

注意:ArkTS 不允许将类作为对象导出,所以使用 export { } 语法。


💡 使用示例

基本路由操作

import { HMRouterUtil } from '../hmRouter/util/HMRouterUtil';

// 简单跳转
HMRouterUtil.push('pages/DetailPage', { id: 123 });

// 异步跳转
await HMRouterUtil.pushAsync('pages/DetailPage', { id: 123 });

// 返回上一页
HMRouterUtil.pop();

完整参数路由操作

import { HMRouterUtil } from '../hmRouter/util/HMRouterUtil';
import {
  HMRouterUtilOptions,
  HMRouterUtilPathCallback
} from '../hmRouter/model/Index';

// 常用参数作为独立参数,其他参数使用 options 对象
HMRouterUtil.push(
  'pages/DetailPage',           // pageUrl
  { id: 123 },                  // param(独立参数)
  {                              // options(可选)
    navigationId: 'MainNavigation',
    skipAllInterceptor: false
  },
  {                              // callback(独立参数,可选)
    onArrival: () => console.log('页面到达'),
    onResult: (popInfo) => console.log('页面返回', popInfo.result)
  }
);

链式调用(推荐)

// 链式调用方式,代码更清晰
HMRouterUtil.to('pages/DetailPage')
  .withParam({ id: 123 })
  .withNavigation('MainNavigation')
  .push();

// 异步链式调用
await HMRouterUtil.to('pages/DetailPage')
  .withParam({ id: 123 })
  .pushAsync();

获取参数

import { HMRouterUtilParamType } from '../hmRouter/model/Index';

// 获取所有参数
const allParam = HMRouterUtil.getCurrentParam(HMRouterUtilParamType.all);

// 获取 URL 参数
const urlParam = HMRouterUtil.getCurrentParam(HMRouterUtilParamType.urlParam);

// 获取路由参数
const routeParam = HMRouterUtil.getCurrentParam(HMRouterUtilParamType.routeParam);

⚠️ 注意事项

1. ArkTS 类型兼容性

ArkTS 不允许在类属性初始化时直接使用对象字面量,需要定义接口并在 aboutToAppear() 中初始化:

// ❌ 错误写法
private param: Object = { id: 123 };

// ✅ 正确写法
interface TestParam {
  id: number;
}

private param: TestParam | null = null;

aboutToAppear() {
  this.param = { id: 123 };
}

2. 枚举值名称

HMParamType 枚举的正确值:

  • all - 所有参数
  • urlParam - URL 参数(不是 url
  • routeParam - 路由参数(不是 route
  • regexParam - 正则匹配参数

3. 类型别名导出

ArkTS 不允许将类作为对象导出:

// ❌ 错误写法
export const HMRouterUtilMgr = HMRouterMgr;

// ✅ 正确写法
export { HMRouterMgr as HMRouterUtilMgr };

📊 封装效果对比

封装前

// 需要手动构建 HMRouterPathInfo 对象
const pathInfo: HMRouterPathInfo = {
  pageUrl: 'pages/DetailPage',
  param: { id: 123 },
  navigationId: 'MainNavigation',
  skipAllInterceptor: false
};
HMRouterMgr.push(pathInfo, callback);

封装后

// 参数直接传递,更简洁直观
HMRouterUtil.push(
  'pages/DetailPage',
  { id: 123 },
  { navigationId: 'MainNavigation', skipAllInterceptor: false },
  callback
);

🎯 设计原则

原则

说明

基于公开 API

封装基于 .d.ets 类型定义,不依赖源码实现

类型统一

统一使用 Object,保持项目代码风格一致

职责分离

类型定义放 model/,工具类放 util/

简化使用

参数直接传递,内部处理复杂对象构建


📝 总结

本文介绍了 HMRouter 封装的第一步:类型定义封装和核心工具类创建。通过封装,我们实现了:

  1. 类型统一:12 个类型别名,统一项目内部使用
  2. API 简化:常用参数独立,其他参数使用 options 对象
  3. 代码复用buildPathInfo 私有方法统一构建路径信息
  4. 完整覆盖:封装 HMRouterMgr 中的所有 40+ 个方法

Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐