1. 路由
官网地址:
https://developer.huawei.com/consumer/cn/doc/harmonyos-references/js-apis-router
1. 概念
路由,其实可以理解为就是页面跳转,页面跳转是指从一个页面导航到另一个页面,并且可以将数据从一个页面传递到另一个页面
- 在鸿蒙应用中,路由负责管理不同页面之间的
跳转和参数传递,它基于轻量级的栈式管理结构,每个页面都有唯一的标识符,所有被访问过的页面都会被放置在页面栈中 - 每当页面跳转时,路由会根据标识符对页面进行入栈或出栈操作,实现页面
跳转和管理 页面栈是一个后进先出的数据结构,用于存储鸿蒙应用中打开的页面- 页面栈的
顶部始终是当前页,而其他页面则按照它们被打开的顺序排列在下面 - 页面栈的
最大容量为32个页面,若超出此限制,可能会导致应用程序出现异常行为,例如页面无法正常压入页面栈或无法正常返回等 - 为了避免超出页面栈的最大容量,可以在页面跳转时,选择适当的页面跳转模式
路由功能通过router对象(或称为router模块)来实现,该对象有两种导入方式
第1种导入方式如下:
js
import router from '@ohos.router';
第2种导入方式如下:
js
import { router } from '@kit.ArkUI';
以上两种导入方式的效果相同
2. 页面跳转
router对象提供了pushUrl()方法和replaceUrl()方法,这两个方法都可以实现页面跳转,它们的区别在于目标页是否会替换当前页,对比如下:
| 方法 | 说明 |
|---|---|
| pushUrl() | 目标页不会 替换当前页,而是将当前页压入页面栈以保留当前页的状态,跳转后可以通过返回操作回到当前页。这种模式适用于常规的页面导航,例如从一个列表页跳转到详情页 |
| replaceUrl() | 目标页会 替换当前页,当前页会被销毁并释放资源 。跳转后无法通过返回操作回到当前页。这种模式适用于需要替换当前页的场景,例如在登录成功后直接跳转到主页 |
pushUrl()方法的基本语法格式如下:
js
router.pushUrl(options, mode?, callback?);
- options参数是一个对象,用于设置
目标页的描述信息,该对象有两个属性:
- url属性表示目标页的路径
- params属性表示传递的参数 (如果传递了参数,则在目标页中可以通过调用
router对象的getParams()方法来获取传递过来的参数。如果不需要传递参数,可以省略params属性)
- mode参数是可选的,用于设置跳转页面使用的模式,包括标准实例模式router.RouterMode.Standard 和单实例模式router.RouterMode.Single,它们的区别在于是否会新建目标页,默认使用标准实例模式,两种模式的说明如下表所示:
| 模式 | 说明 |
|---|---|
| 标准实例模式 | 每次跳转都会新建 一个目标页并压入栈顶。这种模式适用于需要在同一URL下展示不同内容或状态的场景,例如博客的不同文章页面 |
| 单实例模式 | 如果目标页已经在页面栈中,则离栈顶最近的同URL页面会被移动到栈顶并重新加载;如果目标页不存在,则按照标准实例模式跳转。这种模式适用于需要保持页面状态一致性的场景,例如购物APP类的商品详情页面 |
使用案例代码如下:
js
router.pushUrl({
url: 'pages/UserCenter',
params: {
nickName: '张三',
},
}, router.RouterMode.Single)
UserCenter.ets页面这样接收参数:
js
@State userName: string = (router.getParams() as Record<string, string>)['nickName'];
- callback参数是可选的,用于处理成功或失败情况的回调函数。如果省略了mode参数,callback参数可作为第2个参数
注意事项:跳转的页面必须是被@Entry装饰的组件,并且该页面必须注册到entry/src/main/resources/base/profile/main_page.json文件中
3. 页面返回
- 当用户在一个页面完成操作后,可能需要返回到上一个页面 或者返回到指定页面,这就需要用到页面返回功能。在返回的过程中可以传递数据
- outer对象的
back()方法用于实现页面返回功能,这个方法会将用户导航到上一个页面,而且不会重新初始化上一个页面,因此上一个页面的状态和数据都会被保留
back()方法的基本语法格式如下:
js
router.back(options?);
options是一个可选参数,该参数是一个对象,用于设置返回页的描述信息。它有url属性 和params属性。url属性表示返回页面的路径。params属性表示传递的参数
- 如果省略options参数,则表示返回到上一个页面。如果传递了options参数并且传递了返回页面的路径,则表示返回到指定页面
- 如果传递了params属性,则在返回页中可以通过调用router对象的getParams()方法来获取传递过来的参数。如果不需要传递参数,则可以省略params属性
4. Router对象提供的其他方法
除了前面讲到的pushUrl()方法、replaceUrl()方法、getParams()方法、back()方法外,router还提供了其他的方法:
| 方法 | 说明 |
|---|---|
| clear() | 清空页面栈中的所有历史页面,仅保留当前页面作为栈顶页面 |
| getLength() | 获取当前页面栈的数量 |
| getState() | 获取当前页面的状态信息 |
| pushNamedRoute() | 跳转到指定的命名路由页面 |
| hideAlertBeforeBackPage() | 在页面返回时禁用询问对话框 |
| replaceNamedRoute() | 用指定的命名路由页面替换当前页面,并销毁被替换的页面 |
| showAlertBeforeBackPage() | 在页面返回时弹出询问对话框 |
5. 页面传参
父页面传参数给子页面
父页面这样写:
js
router.pushUrl({
url: 'pages/PageTwo',
params: {
name: 'zhangsan',
},
}, router.RouterMode.Single)
子页面这样接收参数:
js
@State nickName: string = (router.getParams() as Record<string, string>)['nickName'];
2. 组件导航
官网地址:
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-navigation-navigation
1. 概念
ArkUI中的组件导航功能包含两个重要的组件:
- Navigation组件
- NavDestination组件
它们分别用于实现导航页和子页
导航页用于放置导航项。子页用于显示导航项对应的内容。
2. 使用
这里我们使用如下两个页面来做测试
- PageOne(首页)
- PageTwo(详情页面)
基于上面两个页面,我们下面来演示一下,如何进行页面跳转以及页面如何进行传值
2.1. 页面跳转
首先我们需要定义系统路由表,官网地址如下:
https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-navigation-navigation

所以我们首先需要在工程resources/base/profile中创建route_map.json文件。添加如下配置信息:
json
{
"routerMap": [
{
"name": "PageOne",
"pageSourceFile": "src/main/ets/pages/PageOne.ets",
"buildFunction": "PageOneBuilder",
"data": {
"description": "首页"
}
},
{
"name": "PageTwo",
"pageSourceFile": "src/main/ets/pages/PageTwo.ets",
"buildFunction": "PageTwoBuilder",
"data": {
"description": "详情页"
}
}
]
}
如下:

然后在跳转目标模块的配置文件module.json5添加路由表配置,如下:
json
"routerMap": "$profile:route_map",
如下:

最后在pages下新建下面两个页面文件:

OK,至此,我们配置信息和页面都准备好了,现在开始在PageOne页面中开始编码,代码如下:
js
/**
* Desc: 首页
*/
@Entry
@Component
struct PageOne {
pathStack: NavPathStack = new NavPathStack();
build() {
Column() {
Navigation(this.pathStack) {
Text('这是首页')
.fontSize(30)
.fontWeight(800)
Button('进入详情页面')
.onClick(() => {
//页面跳转
this.pathStack.pushPathByName('PageTwo', '');
})
}
}
.width('100%')
.height('100%')
}
}
// 跳转页面入口函数
@Builder
export function PageOneBuilder() {
PageOne();
}
PageTwo页面代码如下:
js
/**
* Desc: 详情页面
*/
@Component
struct PageTwo {
@State message: string = '详情页面'
build() {
NavDestination() {
Column() {
Text('这里是详情信息!')
}
.height('100%')
.width('100%')
}
.title(this.message)
}
}
// 跳转页面入口函数
@Builder
export function PageTwoBuilder() {
PageTwo();
}
启动模拟器,访问PageOne页面,如下:

点击按钮,跳转到第二个页面,如下:

OK,到目前为止,页面跳转功能就可以正常使用了
页面跳转方法官网地址如下:

2.2. 传递参数
页面跳转时,如何传递参数呢?
其实非常简单,上面页面跳转时,我们传的是空,现在我们可以传递一个参数试试
PageOne改造代码后,全量如下:
js
/**
* Desc: 首页
*/
@Entry
@Component
struct PageOne {
pathStack: NavPathStack = new NavPathStack();
build() {
Column() {
Navigation(this.pathStack) {
Text('这是首页')
.fontSize(30)
.fontWeight(800)
Button('进入详情页面')
.onClick(() => {
//页面跳转
this.pathStack.pushPathByName('PageTwo', 'PageOne Info');
})
}
}
.width('100%')
.height('100%')
}
}
// 跳转页面入口函数
@Builder
export function PageOneBuilder() {
PageOne();
}
PageTwo改造代码后,全量代码如下:
js
/**
* Desc: 详情页面
*/
@Component
struct PageTwo {
@State message: string = '详情页面';
@State param: string = ''; //保存从首页传来的参数数据
build() {
NavDestination() {
Column() {
Text('这里是详情信息!')
Text('首页传过来数据:' + this.param)
}
.height('100%')
.width('100%')
}
.title(this.message)
.onReady((context: NavDestinationContext) => {
//将首页传过来的数据赋值给变量param
this.param = context.pathInfo.param as string;
})
}
}
// 跳转页面入口函数
@Builder
export function PageTwoBuilder() {
PageTwo();
}
测试如下:

那现在从PageTwo页面翻译PageOne时,如何给PageOne传参数呢?
此时需要在PageOne页面中修改pushPathByName方法了,加上第三个参数,如下:

PageOne页面修改后,全量代码如下:
js
/**
* Desc: 首页
*/
@Entry
@Component
struct PageOne {
pathStack: NavPathStack = new NavPathStack();
@State param: string = ''; //保存从相亲页面传来的参数数据
build() {
Column() {
Navigation(this.pathStack) {
Text('这是首页')
.fontSize(30)
.fontWeight(800)
Text('详情页传过来数据:' + this.param)
Button('进入详情页面')
.onClick(() => {
//页面跳转
this.pathStack.pushPathByName('PageTwo', 'PageOne Info', (popInfo) => {
//popInfo对象保存着详情页传过来的数据
console.log('popInfo====' + JSON.stringify(popInfo))
this.param = popInfo.result['info'];
});
})
}
}
.width('100%')
.height('100%')
}
}
// 跳转页面入口函数
@Builder
export function PageOneBuilder() {
PageOne();
}
PageTwo页面修改后,全量代码如下:
js
/**
* Desc: 详情页面
*/
@Component
struct PageTwo {
@State message: string = '详情页面';
@State param: string = ''; //保存从首页传来的参数数据
pathStack: NavPathStack | undefined = undefined;
popInfo: PopInfo = {
info: 'data from PageTwo'
}
build() {
NavDestination() {
Column() {
Text('这里是详情信息!')
Text('首页传过来数据:' + this.param)
}
.height('100%')
.width('100%')
}
.title(this.message)
.onReady((context: NavDestinationContext) => {
//将首页传过来的数据赋值给变量param
this.param = context.pathInfo.param as string;
//为pathStack变量赋值
this.pathStack = context.pathStack;
})
.onBackPressed(() => {
//将 popInfo 对象数据传回到上一页
this.pathStack?.pop(this.popInfo);
return true;
})
}
}
// 跳转页面入口函数
@Builder
export function PageTwoBuilder() {
PageTwo();
}
interface PopInfo {
info: string
}

点击按钮跳转到PageTwo如下:

然后再点击左上角的返回按钮,返回到首页,如下:

可以看到,确实可以在首页获取到详情页传递过来的数据,测试成功
3. 总结
本文主要介绍了路由组件和组件导航的使用方式,大家在实际开发过程中,可以根据情况选用合适的方式进行页面跳转