鸿蒙 Navigation跨包跳转:系统路由表与自定义路由表
摘要:鸿蒙应用开发中,Navigation组件提供两种跨包路由方式:系统路由表和自定义路由表。系统路由表(API12+)支持动态加载页面,无需import目标文件,易用性高但扩展性一般;自定义路由表需import页面,支持静态/动态加载,扩展性强但维护成本较高。系统路由表通过router_map.json配置实现自动跳转,推荐用于模块解耦场景;自定义路由表适合需要扩展路由信息的场景。开发者可根据需

在鸿蒙应用开发中,随着应用功能日益复杂,模块化开发成为主流。Navigation提供了跨包路由能力,支持在不同模块(HAP、HSP、HAR)之间进行页面跳转。
一、路由方式
Navigation提供两种跨包路由实现方式:
| 路由方式 | 跨包跳转能力 | 可扩展性 | 易用性 |
|---|---|---|---|
| 系统路由表 | 跳转前无需import页面文件,页面按需动态加载 | 可扩展性一般 | 易用性更强,系统自动维护路由表 |
| 自定义路由表 | 跳转前需要import页面文件 | 可扩展性更强 | 易用性一般,需开发者自行维护路由表 |
说明:支持自定义路由表和系统路由表混用。
二、系统路由表
系统路由表是动态路由的一种实现方式。从API version 12开始,Navigation支持使用系统路由表的方式进行动态路由。从API version 23开始,Navigation组件支持跳转到按需加载的HSP页面。
注意:系统路由表支持模拟器但不支持预览器。
实现原理
各业务模块(HAP、HSP、HAR)中需要独立配置router_map.json文件。触发路由跳转时,应用只需要通过NavPathStack提供的路由方法,传入需要路由的页面配置名称,系统会自动完成路由模块的动态加载、页面组件构建,并完成路由跳转。
实现步骤
步骤1:创建router_map.json
在工程resources/base/profile路径下创建router_map.json文件:
{
"routerMap": [
{
"name": "PageOne",
"pageSourceFile": "src/main/ets/pages/PageOne.ets",
"buildFunction": "PageOneBuilder",
"data": {
"description": "this is PageOne"
}
}
]
}
字段说明:
| 字段 | 说明 |
|---|---|
name |
页面名称,用于路由跳转时指定 |
pageSourceFile |
页面源文件路径 |
buildFunction |
页面Builder函数名 |
data |
可选,页面配置数据 |
步骤2:在module.json5中配置路由表
{
"module": {
"routerMap": "$profile:router_map"
}
}
步骤3:配置页面Builder函数
在跳转目标页面,配置入口Builder函数,函数名需与router_map.json中的buildFunction一致:
// 跳转页面入口函数
@Builder
export function PageOneBuilder() {
PageOne();
}
@Component
struct PageOne {
pathStack: NavPathStack = new NavPathStack();
build() {
NavDestination() {
// 页面内容
}
.title('PageOne')
.onReady((context: NavDestinationContext) => {
this.pathStack = context.pathStack;
})
}
}
步骤4:执行路由跳转
@Entry
@Component
struct SystemRoutingTable {
pageStack: NavPathStack = new NavPathStack();
build() {
Navigation(this.pageStack) {
// 导航内容
}
.onAppear(() => {
this.pageStack.pushPathByName('PageOne', null, false);
})
.hideNavBar(true)
}
}
三、自定义路由表
自定义路由表通过给Navigation的navDestination属性设置Builder函数实现,其特点是需要import页面。
静态import vs 动态import
| import方式 | 模块间耦合度 | 实现复杂度 | 性能 |
|---|---|---|---|
| 动态import | 模块间解耦 | 复杂度高 | 性能好,按需加载,跳转前再加载对应页面 |
| 静态import | 模块间耦合 | 复杂度低 | 性能一般,初始化时一次性加载所有依赖的页面 |
建议:推荐使用动态import或系统路由表。
动态import
优势:
-
路由定义可以配置丰富的扩展信息(横竖屏默认模式、是否需要鉴权等)
-
按照名称进行跳转而不是文件路径
-
页面的加载可以使用动态import(按需加载),防止首个页面加载大量代码导致卡顿
实现步骤:
-
定义页面跳转配置项(使用资源文件或ets文件)
-
加载目标跳转页面,通过动态import将页面所在模块在运行时加载
-
在Navigation的
navDestination属性中执行加载的Builder函数
静态import
@Entry
@Component
struct NavigationExample {
@Provide('navPathStack') navPathStack: NavPathStack = new NavPathStack();
private arr: number[] = [1, 2];
@Builder
pageMap(name: string) {
if (name === 'NavDestinationTitle1') {
pageOneTmp();
} else if (name === 'NavDestinationTitle2') {
pageTwoTmp();
}
}
build() {
Column() {
Navigation(this.navPathStack) {
// 导航内容
}
.navDestination(this.pageMap) // 注册路由表
}
}
}
@Component
export struct pageOneTmp {
@Consume('navPathStack') navPathStack: NavPathStack;
build() {
NavDestination() {
Column() {
Text('NavDestinationContent1')
}
}
.title('NavDestinationTitle1')
}
}
最后
两种路由方式对比
| 对比项 | 系统路由表 | 自定义路由表 |
|---|---|---|
| import要求 | 跳转前无需import | 跳转前需要import |
| 页面加载 | 按需动态加载 | 静态import全量加载 / 动态import按需加载 |
| 易用性 | 更强,系统自动维护 | 一般,需自行维护 |
| 可扩展性 | 一般 | 更强 |
| 最低版本 | API 12 | - |
选择建议
| 场景 | 推荐方案 |
|---|---|
| 模块解耦、按需加载 | 系统路由表 |
| 需要扩展路由信息(鉴权等) | 自定义路由表(动态import) |
| 简单场景、快速开发 | 系统路由表 |
| 已有静态import实现 | 静态import(不推荐新项目使用) |
更多推荐


所有评论(0)