在鸿蒙HarmonyOS原生开发中随着应用规模的扩大传统的硬编码路由会导致模块间高度耦合。为了实现页面解耦、统一拦截如登录校验以及跨模块通信开发者通常会引入成熟的路由框架。目前鸿蒙生态中最具代表性的路由方案是官方开源的HMRouter以及社区广泛使用的ZRouter和TheRouter。一、 官方开源方案HMRouterHMRouter 是鸿蒙官方推出的路由管理组件旨在简化应用内原生页面的跳转逻辑。它底层封装了系统的Navigation、NavDestination和NavPathStack通过编译期注解处理器自动生成路由表实现业务与路由的解耦。注解驱动与声明式路由通过HMRouter装饰器声明路由路径支持字符串常量定义并兼容 HAR/HSP/HAP 模块化方案。强大的拦截器机制支持全局拦截、单页面拦截以及跳转时一次性拦截。开发者可以轻松实现未登录拦截、权限校验等逻辑。生命周期与转场动画提供全局与单页面的生命周期回调并内置了 slide、fade、scale 等转场动画支持交互式动画配置。服务路由Service Route除了页面跳转HMRouter 还支持通过HMService注册服务实现跨模块的方法调用与解耦。5. 官方 HMRouter 初始化与页面声明实战 场景在应用启动时初始化路由框架并通过注解声明式定义页面路由实现跨模块的无缝跳转。 typescript 编辑 // 1. 在 EntryAbility 中初始化路由框架 import { HMRouterMgr } from hadss/hmrouter; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { HMRouterMgr.init({ context: this.context }); } } // 2. 使用注解声明页面路由无需手动包裹 NavDestination import { HMRouter, HMRouterMgr } from hadss/hmrouter; HMRouter({ pageUrl: page/detail }) Component export struct DetailPage { // 自动获取路由传递的参数 State param: Object | null HMRouterMgr.getCurrentParam(); build() { Column() { Text(详情页参数: ${JSON.stringify(this.param)}).fontSize(18); Button(返回并携带结果).onClick(() { // 返回上一页并传递结果 HMRouterMgr.pop({ param: { status: success } }); }); } .width(100%) .height(100%) .justifyContent(FlexAlign.Center); } } 6. 全局拦截器实战未登录自动重定向 场景在跳转到个人中心等受保护页面时全局拦截器自动检查登录状态。若未登录则拦截原始请求并重定向至登录页。 typescript 编辑 import { HMRouterMgr, HMInterceptorAction, HMInterceptorInfo } from hadss/hmrouter; // 定义全局登录拦截器 export class LoginGlobalInterceptor { handle(info: HMInterceptorInfo): HMInterceptorAction { const isLogin false; // 模拟未登录状态 if (!isLogin info.targetName page/profile) { // 拦截原始跳转重定向至登录页并携带目标页URL以便登录后返回 HMRouterMgr.push({ pageUrl: page/login, param: { targetUrl: info.targetName }, skipAllInterceptor: true // 登录页跳转跳过拦截器防止死循环 }); return HMInterceptorAction.DO_REJECT; // 拒绝原始跳转 } return HMInterceptorAction.DO_NEXT; // 放行继续执行下一个拦截器或跳转 } } 7. 跨模块服务路由接口与实现解耦 场景基础模块需要调用业务模块的方法如获取用户信息但不允许基础模块直接依赖业务模块。通过 HMService 实现服务注册与发现。 typescript 编辑 // 1. 在业务模块中注册服务 import { HMService } from hadss/hmrouter; export class UserService { HMService({ serviceName: IUserService, singleton: true }) getUserInfo(): string { return 当前用户: HarmonyOS Dev; } } // 2. 在基础模块中获取服务并调用无需 import 实现类 // 通过 HMRouterMgr 获取服务实例 const userService HMRouterMgr.getService(IUserService) as UserService; console.info(userService.getUserInfo());二、 社区进阶方案ZRouter 与 TheRouterZRouter同样基于自定义注解和代码生成实现。它提供了极其优雅的链式调用 API如ZRouter.getInstance().push(Login)其全局拦截器GlobalNavigateInterceptor支持在onNavigate中根据页面的needLogin属性进行重定向和参数替换。TheRouter针对超大型项目的模块化协作TheRouter 通过动态路由表和ServiceProvider机制完美解决了复杂的跨模块依赖注入与服务发现痛点。import { TheRouter, Route, Autowired } from therouter/library; // 1. 声明路由并自动注入参数 Route({ path: http://therouter.com/home }) Component export struct HomePage { Autowired() userId: string ; aboutToAppear(): void { // 使用注解接收对象时必须调用 inject TheRouter.inject(this); } build() { Column() { Text(当前用户ID: ${this.userId}).fontSize(18); } } } // 2. 发起跳转并传递参数 TheRouter .build(http://therouter.com/home) .withString(userId, U12345) .navigation();三、 核心能力路由拦截器Interceptor拦截器是路由框架的核心价值之一。无论是 HMRouter 还是 ZRouter都允许开发者在页面跳转前进行逻辑干预。全局鉴权在跳转目标页面前检查全局登录状态。若未登录则中断原始跳转重定向至登录页并在登录成功后携带原参数继续跳转。埋点与日志在全局拦截器中统一记录用户的页面访问轨迹如srcName jump to targetName无需在每个业务页面手动埋点。import { HMInterceptor, HMInterceptorAction, IHMInterceptor, IHMInterceptorChain, HMRouterMgr } from hadss/hmrouter; HMInterceptor({ interceptorName: LoginCheckInterceptor }) export class LoginCheckInterceptor implements IHMInterceptor { async intercept(chain: IHMInterceptorChain): Promisevoid { const info chain.getRouterInfo(); const isLogin false; // 模拟未登录状态 if (!isLogin info.targetName page/profile) { // 拦截原始跳转重定向至登录页 info.context.getPromptAction().showToast({ message: 请先登录 }); HMRouterMgr.push({ pageUrl: page/login, param: { targetUrl: info.targetName }, skipAllInterceptor: true // 登录页跳转跳过拦截器防止死循环 }); await chain.onIntercept(); // 拦截原始请求 } else { await chain.onContinue(); // 放行继续执行跳转 } } }四、 宿主容器与路由栈管理路由表与名称一致性使用pushPathByName时传入的名称必须与配置文件如route_map.json或注解中的pageUrl完全一致否则会导致跳转白屏或失败。参数类型安全跨页面传递复杂对象时建议统一定义 Interface如DetailParam并导出避免在多个页面中“随手拼对象”导致字段缺失或类型错误。编译插件版本对齐使用 HMRouter 等基于代码生成的框架时必须确保编译插件如hadss/hmrouter-plugin与核心库的版本严格一致否则会导致编译失败或路由表生成异常。宿主容器不可缺失HMRouter 依赖系统的 Navigation 能力必须在根页面通常是Entry组件中包裹HMNavigation或Navigation(ZRouter.getNavStack())容器否则 push 操作会因找不到“宿主栈”而失效。import { HMNavigation, HMDefaultGlobalAnimator } from hadss/hmrouter; // 在根页面Entry中必须包裹 HMNavigation 容器 Entry Component struct Index { build() { Column() { HMNavigation({ navigationId: mainNavigation, homePageUrl: page/home, // 首页路由地址 options: { standardAnimator: HMDefaultGlobalAnimator.STANDARD_ANIMATOR } }) } .width(100%) .height(100%); } }五、HMRouter 初始化与页面声明实战场景在应用启动时初始化路由框架并通过注解声明式定义页面路由实现跨模块的无缝跳转。// 1. 在 EntryAbility 中初始化路由框架 import { HMRouterMgr } from hadss/hmrouter; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { HMRouterMgr.init({ context: this.context }); } } // 2. 使用注解声明页面路由无需手动包裹 NavDestination import { HMRouter, HMRouterMgr } from hadss/hmrouter; HMRouter({ pageUrl: page/detail }) Component export struct DetailPage { // 自动获取路由传递的参数 State param: Object | null HMRouterMgr.getCurrentParam(); build() { Column() { Text(详情页参数: ${JSON.stringify(this.param)}).fontSize(18); Button(返回并携带结果).onClick(() { // 返回上一页并传递结果 HMRouterMgr.pop({ param: { status: success } }); }); } .width(100%) .height(100%) .justifyContent(FlexAlign.Center); } }六、 全局拦截器实战未登录自动重定向场景在跳转到个人中心等受保护页面时全局拦截器自动检查登录状态。若未登录则拦截原始请求并重定向至登录页。import { HMRouterMgr, HMInterceptorAction, HMInterceptorInfo } from hadss/hmrouter; // 定义全局登录拦截器 export class LoginGlobalInterceptor { handle(info: HMInterceptorInfo): HMInterceptorAction { const isLogin false; // 模拟未登录状态 if (!isLogin info.targetName page/profile) { // 拦截原始跳转重定向至登录页并携带目标页URL以便登录后返回 HMRouterMgr.push({ pageUrl: page/login, param: { targetUrl: info.targetName }, skipAllInterceptor: true // 登录页跳转跳过拦截器防止死循环 }); return HMInterceptorAction.DO_REJECT; // 拒绝原始跳转 } return HMInterceptorAction.DO_NEXT; // 放行继续执行下一个拦截器或跳转 } }七、跨模块服务路由接口与实现解耦场景基础模块需要调用业务模块的方法如获取用户信息但不允许基础模块直接依赖业务模块。通过HMService实现服务注册与发现。// 1. 在业务模块中注册服务 import { HMService } from hadss/hmrouter; export class UserService { HMService({ serviceName: IUserService, singleton: true }) getUserInfo(): string { return 当前用户: HarmonyOS Dev; } } // 2. 在基础模块中获取服务并调用无需 import 实现类 // 通过 HMRouterMgr 获取服务实例 const userService HMRouterMgr.getService(IUserService) as UserService; console.info(userService.getUserInfo());