鸿蒙开发:HMRouter封装教程(一)
HMRouter 是鸿蒙应用开发中功能强大的路由框架,提供了路由拦截、页面生命周期、自定义转场动画等丰富功能。但在实际项目中,直接使用类型不统一:框架使用ESObject,项目可能更倾向于使用Object参数复杂对象构建繁琐,需要手动组装多个可选参数代码重复:每次跳转都需要构建完整的路径信息对象维护困难:如果框架升级,需要修改大量业务代码因此,我们需要对 HMRouter 进行封装,提供更简洁、统
📖 前言
HMRouter 是鸿蒙应用开发中功能强大的路由框架,提供了路由拦截、页面生命周期、自定义转场动画等丰富功能。但在实际项目中,直接使用 HMRouterMgr 可能存在以下问题:
- 类型不统一:框架使用
ESObject,项目可能更倾向于使用Object - 参数复杂:
HMRouterPathInfo对象构建繁琐,需要手动组装多个可选参数 - 代码重复:每次跳转都需要构建完整的路径信息对象
- 维护困难:如果框架升级,需要修改大量业务代码
因此,我们需要对 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 个核心类型:
|
类型别名 |
原始类型 |
说明 |
|
|
|
路由路径信息 |
|
|
|
路由回调 |
|
|
|
页面参数 |
|
|
|
页面返回信息 |
|
|
|
参数类型枚举 |
|
|
|
拦截器接口 |
|
|
|
生命周期接口 |
|
|
|
动画接口 |
|
|
自定义接口 |
路由选项接口 |
|
|
|
生命周期所有者 |
|
|
|
服务响应类型 |
|
|
|
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;
}
设计思路:
param和callback作为独立参数,因为使用频率高- 其他参数(
navigationId、interceptors等)放在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 关键设计点
- 参数统一使用 Object:所有
ESObject统一替换为Object - 常用参数独立:
param和callback作为独立参数,使用更方便 - 条件构建对象:使用
if判断构建pathInfo,避免 ArkTS 不支持展开运算符的问题 - 完整封装:封装 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 |
封装基于 |
|
类型统一 |
统一使用 |
|
职责分离 |
类型定义放 |
|
简化使用 |
参数直接传递,内部处理复杂对象构建 |
📝 总结
本文介绍了 HMRouter 封装的第一步:类型定义封装和核心工具类创建。通过封装,我们实现了:
- ✅ 类型统一:12 个类型别名,统一项目内部使用
- ✅ API 简化:常用参数独立,其他参数使用 options 对象
- ✅ 代码复用:
buildPathInfo私有方法统一构建路径信息 - ✅ 完整覆盖:封装 HMRouterMgr 中的所有 40+ 个方法
更多推荐




所有评论(0)