HarmonyOS NEXT 最强路由管理 HMRouter 完全指南 📅 发布时间:2026/7/13 21:50:35 👁️ 浏览次数: HMRouter 是目前鸿蒙生态中功能最完善的路由框架它封装了系统 Navigation 的复杂细节用注解方式让页面跳转变得简单高效。本文将带你从零开始全面掌握 HMRouter 的配置、跳转、拦截、生命周期等核心能力。一、为什么是 HMRouter在 HarmonyOS 中官方提供了两种路由方案Router和Navigation。Router 是早期的页面路由方案存在 32 条页面栈上限、不支持路由拦截等限制官方已不再推荐使用 。Navigation 是当前官方主推的组件化导航方案功能更强大但在实际开发中仍有一些痛点每个页面都需要手动包裹NavDestination增加代码层级缺少统一的路由拦截机制页面生命周期管理需要自行实现跨模块跳转配置繁琐HMRouter正是为解决这些问题而生。它在底层封装了 Navigation 的系统能力提供了一套基于注解的声明式路由方案让开发者几乎无需关心 Navigation 的复杂细节 。HMRouter 核心能力一览能力说明 注解驱动HMRouter声明页面路径HMInterceptor定义拦截器 跨模块跳转完美支持 HAR/HSP 之间的页面跳转 路由拦截支持全局/局部拦截器可实现登录校验、权限控制 页面生命周期自定义生命周期处理器监听页面事件✨ 自定义转场动画支持页面级和全局转场动画配置 单例页面通过singleton: true实现页面复用 Dialog 页面将页面以弹窗形式展示 返回传参支持页面返回时携带参数二、快速上手从零配置 HMRouter2.1 安装依赖首先安装 HMRouter 核心库bashohpm install hadss/hmrouter如果需要使用自定义转场动画还需安装过渡动画库bashohpm install hadss/hmrouter-transitions2.2 配置编译插件修改工程根目录的hvigor/hvigor-config.json添加路由编译插件依赖 json{ dependencies: { hadss/hmrouter-plugin: ^1.0.0-rc.10 } }然后在使用 HMRouter 的模块entry/har/hsp的hvigorfile.ts中引入插件entry 模块Haptypescript// entry/hvigorfile.ts import { hapTasks } from ohos/hvigor-ohos-plugin; import { hapPlugin } from hadss/hmrouter-plugin; export default { system: hapTasks, plugins: [hapPlugin()] };Har 模块使用harPlugin()Hsp 模块使用hspPlugin()2.3 工程配置在build-profile.json5中配置useNormalizedOHMUrl为true使框架能动态导入模块 json{ buildOption: { useNormalizedOHMUrl: true } }2.4 初始化路由框架在EntryAbility的onCreate中初始化HMRouterMgrtypescript// entry/src/main/ets/entryability/EntryAbility.ets import { HMRouterMgr } from hadss/hmrouter; export default class EntryAbility extends UIAbility { onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void { HMRouterMgr.init({ context: this.context }); } }2.5 定义路由入口在首页中使用HMNavigation作为路由容器 typescript// entry/src/main/ets/pages/Index.ets import { HMDefaultGlobalAnimator, HMNavigation, HMRouterMgr } from hadss/hmrouter; import { AttributeUpdater } from kit.ArkUI; class NavModifier extends AttributeUpdaterNavigationAttribute { initializeModifier(instance: NavigationAttribute): void { instance.mode(NavigationMode.Stack); instance.hideTitleBar(true); instance.hideToolBar(true); } } Entry Component export struct Index { modifier: NavModifier new NavModifier(); build() { Column() { HMNavigation({ navigationId: mainNavigation, options: { standardAnimator: HMDefaultGlobalAnimator.STANDARD_ANIMATOR, dialogAnimator: HMDefaultGlobalAnimator.DIALOG_ANIMATOR, modifier: this.modifier } }) { // 首页内容 Button(跳转到登录页) .onClick(() { HMRouterMgr.push({ pageUrl: LoginPage }); }) } } .height(100%) .width(100%) } }2.6 创建第一个页面使用HMRouter注解声明页面 typescript// entry/src/main/ets/views/LoginPage.ets import { HMRouter } from hadss/hmrouter; HMRouter({ pageUrl: LoginPage }) Component export struct LoginPage { build() { Column() { Text(登录页面) Button(返回) .onClick(() { HMRouterMgr.pop(); }) } .width(100%) .height(100%) .justifyContent(FlexAlign.Center) } }注意事项HMRouter装饰的组件必须使用export导出默认页面目录为src/main/ets/components可通过hmrouter_config.json的scanDir自定义三、页面跳转与传参3.1 基础跳转typescript// push压栈跳转保留当前页面 HMRouterMgr.push({ pageUrl: ProductDetail }); // replace替换当前页面 HMRouterMgr.replace({ pageUrl: ProductDetail }); // pop返回上一页 HMRouterMgr.pop(); // pop 返回并携带参数 HMRouterMgr.pop({ param: { success: true } });3.2 跳转传参发送方typescriptHMRouterMgr.push({ pageUrl: ProductDetail, param: { productId: 12345, title: 华为Mate 60 } });接收方typescriptHMRouter({ pageUrl: ProductDetail }) Component export struct ProductDetail { State productId: string ; State title: string ; aboutToAppear(): void { const param HMRouterMgr.getCurrentParam(); if (param) { this.productId param.productId; this.title param.title; } } }3.3 页面返回结果回调跳转时注册onResult回调接收返回页面的数据 typescriptHMRouterMgr.push({ pageUrl: EditProfile, param: { userId: 123 } }, { onResult: (popInfo: HMPopInfo) { const fromPage popInfo.srcPageInfo.name; const result popInfo.result; console.log(从 ${fromPage} 返回数据${JSON.stringify(result)}); // 处理返回数据如刷新页面 } });返回页发送数据typescript// 在 EditProfile 页面中 HMRouterMgr.pop({ param: { updated: true, newName: 张三 } });3.4 返回指定页面在复杂跳转链路中如 A → B → C → D可直接返回到指定页面并传参 typescript// 从 D 页面直接返回到 A 页面 HMRouterMgr.pop({ navigationId: mainNavigation, pageUrl: HomePage, // 目标页面路径 param: { from: DetailPage, action: back } });3.5 跨模块跳转HMRouter 完美支持 HAR/HSP 模块间的跳转。假设cart模块需要跳转到entry模块的页面 1. 在 cart 模块的hvigorfile.ts中配置编译插件typescript// cart/hvigorfile.ts import { hspTasks } from ohos/hvigor-ohos-plugin; import { hspPlugin } from hadss/hmrouter-plugin; export default { system: hspTasks, plugins: [hspPlugin()] };2. entry 模块依赖 cart 模块json// entry/oh-package.json5 { dependencies: { cart: file:../cart } }3. 在 cart 模块中定义页面typescript// cart/src/main/ets/views/CartDetail.ets HMRouter({ pageUrl: CartDetail }) Component export struct CartDetail { // ... }4. entry 模块跳转typescriptHMRouterMgr.push({ pageUrl: CartDetail });四、路由拦截器登录校验与权限控制拦截器是 HMRouter 最强大的功能之一可在跳转前执行业务逻辑常用于登录校验、权限验证、埋点统计等场景 。4.1 定义拦截器实现IHMInterceptor接口使用HMInterceptor注解 typescriptimport { HMInterceptor, IHMInterceptor, HMInterceptorAction, HMInterceptorInfo } from hadss/hmrouter; HMInterceptor({ interceptorName: LoginCheckInterceptor }) export class LoginCheckInterceptor implements IHMInterceptor { handle(info: HMInterceptorInfo): HMInterceptorAction { // 检查登录状态 const isLogin AppStorage.getboolean(isLogin) ?? false; if (isLogin) { // 已登录继续跳转 return HMInterceptorAction.DO_NEXT; } else { // 未登录提示并跳转到登录页 info.context.getPromptAction().showToast({ message: 请先登录 }); HMRouterMgr.push({ pageUrl: LoginPage, skipAllInterceptor: true // 登录页跳过拦截防止死循环 }); // 拒绝原始跳转 return HMInterceptorAction.DO_REJECT; } } }4.2 使用拦截器局部拦截器仅对指定页面生效typescriptHMRouter({ pageUrl: ShoppingCart, interceptors: [LoginCheckInterceptor] // 数组形式支持多个 }) Component export struct ShoppingCart { // ... }全局拦截器对所有跳转生效typescriptHMInterceptor({ interceptorName: GlobalLoggerInterceptor, global: true, // 全局拦截器 priority: 10 // 优先级数字越大越先执行 }) export class GlobalLoggerInterceptor implements IHMInterceptor { handle(info: HMInterceptorInfo): HMInterceptorAction { console.log([路由] 从 ${info.srcPage} 跳转到 ${info.targetName}); return HMInterceptorAction.DO_NEXT; } }4.3 拦截器执行顺序按priority降序执行数字越大越优先同一优先级下执行顺序为发起页面拦截器 → 目标页面拦截器 → 全局拦截器五、页面生命周期管理HMRouter 提供了比系统更丰富的生命周期回调通过HMLifecycle注解定义生命周期处理器 。5.1 定义生命周期typescriptimport { HMLifecycle, IHMLifecycle, HMLifecycleContext } from hadss/hmrouter; HMLifecycle({ lifecycleName: PageLifecycle }) export class PageLifecycle implements IHMLifecycle { // 页面显示时触发 onShown(ctx: HMLifecycleContext): void { console.log(页面显示); } // 页面隐藏时触发 onHidden(ctx: HMLifecycleContext): void { console.log(页面隐藏); } // 返回键按下时触发返回 true 表示拦截false 表示执行默认返回 onBackPressed(ctx: HMLifecycleContext): boolean { console.log(用户按下返回键); return false; // 执行默认返回 } // 页面即将出现 onWillAppear(ctx: HMLifecycleContext): void { console.log(页面即将出现); } // 页面即将消失 onWillDisappear(ctx: HMLifecycleContext): void { console.log(页面即将消失); } }5.2 绑定生命周期typescriptHMRouter({ pageUrl: HomePage, lifecycle: PageLifecycle // 关联生命周期处理器 }) Component export struct HomePage { // ... }5.3 典型场景两次返回退出应用typescriptHMLifecycle({ lifecycleName: ExitAppLifecycle }) export class ExitAppLifecycle implements IHMLifecycle { private lastTime: number 0; onBackPressed(ctx: HMLifecycleContext): boolean { const now new Date().getTime(); if (now - this.lastTime 1000) { this.lastTime now; ctx.uiContext.getPromptAction().showToast({ message: 再次返回退出应用 }); return true; // 拦截本次返回 } return false; // 执行返回退出应用 } }在首页绑定该生命周期即可实现双击返回退出功能 。六、自定义转场动画6.1 定义页面动画使用HMAnimator注解定义动画类 typescriptimport { HMAnimator, IHMAnimator, HMAnimatorHandle } from hadss/hmrouter; HMAnimator({ animatorName: SlideUpAnimator }) export class SlideUpAnimator implements IHMAnimator { effect(enterHandle: HMAnimatorHandle, exitHandle: HMAnimatorHandle): void { // 入场动画从底部滑入 enterHandle.start((translate: any) { translate.y(100%).y(0); }, { duration: 300 }); // 出场动画滑到底部 exitHandle.start((translate: any) { translate.y(0).y(100%); }, { duration: 300 }); } }6.2 使用动画在目标页面的HMRouter中指定动画 typescriptHMRouter({ pageUrl: DetailPage, animator: SlideUpAnimator // 使用自定义动画 }) Component export struct DetailPage { // ... }6.3 全局默认动画在HMNavigation的options中配置全局动画 typescriptHMNavigation({ navigationId: mainNavigation, options: { standardAnimator: HMDefaultGlobalAnimator.STANDARD_ANIMATOR, dialogAnimator: HMDefaultGlobalAnimator.DIALOG_ANIMATOR, // ... } })七、高级特性7.1 单例页面当页面初始化开销较大且需要频繁复用时如视频播放页可配置为单例模式 typescriptHMRouter({ pageUrl: LivePlayer, singleton: true // 页面栈中只有一个实例 }) Component export struct LivePlayer { // ... }7.2 Dialog 页面将页面以弹窗形式展示 typescriptHMRouter({ pageUrl: PrivacyDialog, dialog: true }) Component export struct PrivacyDialog { build() { Stack({ alignContent: Alignment.Center }) { Column() { Text(隐私协议弹窗) // ... } .backgroundColor(Color.White) .borderRadius(16) .padding(20) } .width(100%) .height(100%) .backgroundColor(rgba(0,0,0,0.5)) } }7.3 指定页面扫描目录默认扫描src/main/ets/components可通过配置文件自定义 在项目根目录创建hmrouter_config.jsonjson{ scanDir: [src/main/ets/views, src/main/ets/pages] }八、最佳实践与常见问题8.1 最佳实践统一管理页面路径常量typescript// constants/PageConstants.ets export class PageConstants { static readonly HOME HomePage; static readonly LOGIN LoginPage; static readonly PRODUCT_DETAIL ProductDetail; }合理使用拦截器层级全局拦截器处理通用逻辑埋点、日志局部拦截器处理页面特定逻辑表单校验。避免拦截器死循环在拦截器跳转登录页时务必设置skipAllInterceptor: true。模块化开发每个独立功能模块HSP/HAR独立配置编译插件实现模块间解耦 。8.2 常见问题Q跳转时提示页面未找到A检查HMRouter的pageUrl是否与跳转时一致确认页面在扫描目录下默认components或配置scanDir。QHAR 模块中的页面无法跳转A确保 HAR 模块的hvigorfile.ts中配置了harPlugin()并在宿主模块的oh-package.json5中依赖该 HAR 。Q如何调试路由跳转A可配合系统NavPathStack的getAllPathName()方法查看当前页面栈。九、参考资源HMRouter Gitee 仓库官方示例代码接口文档FAQ 常见问题HMRouter 原理介绍HMRouter 通过注解驱动和插件化编译的方式极大地简化了 HarmonyOS 应用的路由管理。无论是基础的页面跳转、跨模块通信还是复杂的拦截器、生命周期管理HMRouter 都能提供优雅的解决方案。建议在新项目中直接采用 HMRouter可以显著提升路由相关的开发效率。
我简直爱死这些App了 今天分享7个免费App,全部完全免费,良心好用。所有App下载方法文章末尾提供APP介绍Keymemo一款能让你拥有超强记忆的神器!可以把平时记不住的知识点,以文字形式输入进去,它会自动生成知识卡片,每张知识卡片都… 2026/7/13 21:48:34
从Demo到实战:Darcula LAF组件示例大全与应用场景 从Demo到实战:Darcula LAF组件示例大全与应用场景 【免费下载链接】Darcula Darcula Look and Feel 项目地址: https://gitcode.com/gh_mirrors/da/Darcula Darcula Look and Feel(LAF)是一款深受开发者喜爱的Java Swing界面主题&… 2026/7/13 21:48:34
鸿蒙智能体开发实战:21.使用知识库 前言 在上一篇文章中,我们详细介绍了如何在小艺开放平台上创建和发布知识库。但知识库本身只是一个"资料仓库",只有将其整合到智能体中,配置合适的检索策略,才能真正发挥知识库的价值。 知识库与智能体的关系可以类比为… 2026/7/13 21:46:33
在线一键重装系统技术解析:告别U盘重装烦恼 还在为系统重装必须制作启动U盘而烦恼吗?每次重装系统都要先找U盘、下载镜像、制作启动盘,还要进BIOS调整启动顺序,这一套流程下来至少半小时。更不用说遇到新版BIOS找不到U盘启动选项,或者制作启动盘失败的尴尬情况。 最近出现的… 2026/7/13 23:23:01
VSCode 4大核心配置文件解析:settings.json 与 tasks.json 在编译路径控制上的 3 种方案对比 VSCode编译路径控制终极指南:三大配置方案深度对比与实战在开发C项目时,编译生成文件的路径管理往往成为影响工作效率的关键细节。一个合理的输出路径结构不仅能保持项目整洁,还能避免不同构建目标之间的冲突。VSCode作为现代开发者的主力编辑… 2026/7/13 23:23:01
TC78H651AFNG与STM32L053R8的直流电机驱动方案 1. 项目背景与核心器件选型在工业自动化和消费电子领域,直流有刷电机因其结构简单、控制方便、成本低廉等优势,仍然占据着重要市场份额。根据市场调研数据显示,2023年全球有刷直流电机市场规模达到78亿美元,预计到2028年将增长至1… 2026/7/13 23:19:00
直流负载管理方案:欧姆龙G6D-ASI与TI TM4C129LNCZAD的工业级应用 1. 直流负载管理的行业痛点与解决方案在工业自动化、新能源发电和电力电子领域,直流负载管理一直是个棘手的技术难题。传统方案通常采用机械式接触器或纯MOSFET开关,前者存在响应速度慢、体积庞大的问题,后者则面临导通损耗高、散热设计复杂的… 2026/7/13 23:17:00
Vivado 2023.1 编辑器乱码:3种主流外部编辑器(VS Code/Sublime/Vim)编码同步方案 Vivado 2023.1 编辑器乱码:3种主流外部编辑器编码同步方案 FPGA工程师们经常面临一个令人头疼的问题:在VS Code、Sublime或Vim中精心编写的代码,在Vivado中打开时却变成了一堆乱码。这不仅影响代码的可读性,还可能导致注释失效、团… 2026/7/13 23:17:00
HTTP Catcher 2.8.0 iOS 抓包实战:3步配置证书,解密HTTPS流量(附Wi-Fi代理设置) HTTP Catcher 2.8.0 iOS抓包深度指南:从HTTPS解密到实战排错1. 移动端抓包工具的核心价值在移动应用开发和测试过程中,网络请求分析是定位问题的关键环节。传统桌面端抓包工具如Charles、Fiddler虽然功能强大,但存在明显的局限性——它们需要… 2026/7/13 23:10:59
HS2-HF Patch终极指南:如何用3步解决Honey Select 2的70+个痛点 HS2-HF Patch终极指南:如何用3步解决Honey Select 2的70个痛点 【免费下载链接】HS2-HF_Patch Automatically translate, uncensor and update HoneySelect2! 项目地址: https://gitcode.com/gh_mirrors/hs/HS2-HF_Patch 你是否曾经在Honey Select 2中遇到过… 2026/7/13 0:01:19
语音转文字工具AsrTools:让音频整理变得简单高效 语音转文字工具AsrTools:让音频整理变得简单高效 【免费下载链接】AsrTools ✨ AsrTools: Smart Voice-to-Text Tool | Efficient Batch Processing | User-Friendly Interface | No GPU Required | Supports SRT/TXT Output | Turn your audio into accurate text … 2026/7/13 0:03:19
基于深度学习的蘑菇或花卉或动漫人物或中草药货水果蔬菜等识别系统31(设计源文件+万字报告+讲解)(支持资料、图片参考_相关定制)_ 基于深度学习的蘑菇或花卉或动漫人物或中草药货水果蔬菜等识别系统31(设计源文件万字报告讲解)(支持资料、图片参考_相关定制)_ 独家界面!不会重复,此项目属于本人原创,若有雷同,均是盗卖,各位买… 2026/7/13 0:05:20
Git reset 与 revert 深度对比:5个关键差异与 3 种典型应用场景 Git Reset 与 Revert 深度对比:5个关键差异与3种典型应用场景在团队协作开发中,代码版本管理如同行走钢丝——一步失误可能导致整个项目陷入混乱。作为Git进阶用户,你是否曾在深夜面对错误的提交束手无策?是否在强制推送后收到同事… 2026/7/13 8:31:55
GitHub 学生包申请避坑:5个常见失败原因与开发者工具调试方案 GitHub 学生包申请技术排障指南:5个高频失败场景与开发者工具实战方案第一次尝试申请GitHub学生包时,我盯着屏幕上那个不断转圈的加载动画整整15分钟,最终只等来了一行冰冷的错误提示。这可能是许多开发者共同的经历——明明按照教程操作&… 2026/7/13 9:31:08
冒烟测试用例设计规范:5%-10%覆盖率下的3类核心场景与执行标准 冒烟测试用例设计的黄金法则:5%-10%覆盖率下的精准筛选策略在快节奏的敏捷开发环境中,冒烟测试作为质量保障的第一道防线,其重要性不言而喻。当测试资源有限而时间紧迫时,如何从海量测试用例中精准筛选出那关键的5%-10%࿰… 2026/7/13 2:34:55