# 7.4:页面跳转(Router、Ability)
页面跳转可以分为页面内跳转和页面间跳转,页面内跳转是指所跳转的页面在同一个 Ability
内部,它们之间的跳转可以使用 Router
或者 Navigator
的方式;页面间跳转是指所跳转的页面属与不同的 Ability
,这种跳转需要借助 featureAbility
实现,跳转示意图如下所示:
本节将简单介绍这两种方式的页面跳转。
# 7.4.1:页面内跳转
页面内跳转的实现比较简单,直接使用ArkUI开发框架提供的 Router
或者 Navigator
就可以了, Navigator
本质上是对 Router
的封装,这里就简单介绍一下 Router
的使用,想了解 Navigator
的小伙伴请参考官网文档。
# 7.4.1.1:router定义介绍
declare namespace router {
function push(options: RouterOptions):void;
function replace(options: RouterOptions):void;
function back(options?: RouterOptions ):void;
function clear():void;
function getLength():string;
function getState():RouterState;
function enableAlertBeforeBackPage(options: EnableAlertOptions):void;
function disableAlertBeforeBackPage():void;
function getParams(): Object;
}
2
3
4
5
6
7
8
9
10
11
- push:打开新的页面,新页面在栈顶位置,
RouterOptions
定义了以下参数:- url:目标页面的路径,该路径必须在 config.json 的
pages
下配置,否则不起作用。 - params:可选参数,向目标页面传递参数。
- url:目标页面的路径,该路径必须在 config.json 的
- replace:新页面替换当前页面并把当前页面销毁。
- back:返回上一页。
- clear:清空路由栈里的其它页面。
- getLength:获取当前路由栈里的页面数量。
- getState:获取当前页面的状态,
RouterState
参数说明如下:- index:当前页面是第几个打开的。
- path:当前页面的路径。
- name:当前页面的名称。
- enableAlertBeforeBackPage:
- disableAlertBeforeBackPage:
- getParams:获取通过路由传递过来的参数。
# 7.4.1.2:router使用介绍
引入router
使用
router
之前,先要引入router
,引入方式如下:import router from '@ohos.router';
1页面跳转
页面跳转使用
router.push
方法,简单样例如下所示:// 第一个页面 @Entry @Component struct ComponentTest { build() { Column({space: 10}) { Text('第一个页面') .fontSize(30) .width('100%') .textAlign(TextAlign.Center) Button('打开下一页') .onClick(() => { router.push({ // 使用push入栈一个新页面 url: "pages/second" // 通过url指定新打开的页面 }) }) } .size({width: '100%', height: '100%'}) } } // 第二个页面 @Entry @Component struct Second { build() { Column({space: 10}) { Text('第二个页面') .fontSize(30) .width('100%') .textAlign(TextAlign.Center) Button('返回上一页') .onClick(() => { router.back(); // 返回上一页,当前页面会销毁 }) } .size({width: '100%', height: '100%'}) } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38样例运行结果如下所示:
参数传递
当通过
router
打开新页面需要传递参数时,可以使用RouterOptions
的params
参数传递一个对象,然后在接收方以router.getParams()
的方式拿到传递过来的对象,取值的话以.key
的形式取值(注意:从 3.1.6.5 版本起,取值方式变更为['key']
的形式),样例如下:// 第一个页面 @Entry @Component struct ComponentTest { build() { Column({space: 10}) { Text('第一个页面') .fontSize(30) .width('100%') .textAlign(TextAlign.Center) Button('打开下一页') .onClick(() => { router.push({ url: "pages/second", // 打开新页面 params: {value: 'Hi'} // 给新页面传递一个对象,key为value,取值以.value的形式 }) }) } .size({width: '100%', height: '100%'}) } } // 第二个页面 @Entry @Component struct Second { // 3.1.5.5版本之前,取值方式为:router.getParams().key private value: string = router.getParams().value; // 从3.1.6.5版本起,取值方式为:router.getParams()['key'] private value: string = router.getParams()['value']; build() { Column({space: 10}) { Text('第二个页面:' + this.value) // 使用获取过来的参数 .fontSize(30) .width('100%') .textAlign(TextAlign.Center) Button('返回上一页') .onClick(() => { router.back(); // 返回上一页 }) } .size({width: '100%', height: '100%'}) } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49样例运行结果如下图所示:
📢:感谢 lx2323658175 (opens new window) 指出 3.1.6.5 版本 router 的取值方式做了变更,笔者写该电子书时使用的 SDK 版本为 3.1.5.5,该版本的取值方式为 router.getParams().key 的形式,从 3.1.6.5 版本起,取值方式变更为:router.getParams()['key'] 的形式,特此说明。
# 7.4.2:页面间跳转
页面间跳转需要借助 featureAbility
模块的 startAbility()
方法,该方法和 router
的功能类似,可以支持参数传递以及打开指定页面等。
# 7.4.2.1:featureAbility定义介绍
declare namespace featureAbility {
/**省略部分方法*/
function startAbility(parameter: StartAbilityParameter, callback: AsyncCallback<number>): void;
function startAbility(parameter: StartAbilityParameter): Promise<number>;
function startAbilityForResult(parameter: StartAbilityParameter, callback: AsyncCallback<AbilityResult>): void;
function startAbilityForResult(parameter: StartAbilityParameter): Promise<AbilityResult>;
}
2
3
4
5
6
7
- startAbility:打开指定 Ability ,在不指定开目标 Ability 里的页面时,则默认打开 Ability 的第一个页面。
- parameter:设置打开 Ability 的参数,说明如下:
- want:打开目标 Ability 的配置项。
- bundleName:目标 Ability 的包名称。
- abilityName:目标 Ability 的全路径。
- params:传递给目标 Ability 的参数。可以在该参数里指定需要打开的页面。
- want:打开目标 Ability 的配置项。
- parameter:设置打开 Ability 的参数,说明如下:
# 7.4.2.2:打开Ability的默认首页面
创建第二个 Ability ,依次点击 File -> new -> Ablity -> Empty Page Ability(eTS) ,添加 SettingAbility ,如下图所示:
点击 Finish 后, OpenHarmony 代码结构如下图所示:
在 default 的 pages 下的 index.ets 添加跳转功能:引入 featureAbility 模块,然后通过 featureAbility 的
startAbility()
方法打开目标 Ability。// 引入featureAbility import featureAbility from '@ohos.ability.featureAbility'; @Entry @Component struct Index { build() { Column() { Button('open about ability') .onClick(() => { // 打开目标Ability featureAbility.startAbility({ want: { // 目标Ability所在的bundleName,也就是config.json里配置的bundleName bundleName: "com.example.myapplication", // 目标Ability的全路径 abilityName: "com.example.myapplication.SettingAbility" } }) .then((data) => { console.info('Operation successful. Data: ' + JSON.stringify(data)) }) .catch((error) => { console.error('Operation failed. Cause: ' + JSON.stringify(error)); }) }) } .padding(10) .width('100%') .height('100%') } }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31修改SettingAbility的默认首页面,添加如下文案:
@Entry @Component struct Index { build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { Text('我是SettingAbility的默认首页面') .fontSize(50) .fontWeight(FontWeight.Bold) } .width('100%') .height('100%') } }
1
2
3
4
5
6
7
8
9
10
11运行结果如下图所示:
# 7.4.2.3:打开Ability的指定页面
在 SettingAbility 的 pages 下添加第二个页面:second.ets,代码如下所示:
@Entry @Component struct Second { build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { Text('你好,我是SettingAbility的第二个页面') .fontSize(50) .fontWeight(FontWeight.Bold) } .width('100%') .height('100%') } }
1
2
3
4
5
6
7
8
9
10
11修改打开 Ability 的代码,添加 url 参数,代码如下:
featureAbility.startAbility({ want: { bundleName: "com.example.myapplication", abilityName: "com.example.myapplication.SettingAbility", // 添加uri参数,指定打开SettingAbility下的second页面。 uri: "pages/second" } }) .then((data) => { console.info('Operation successful. Data: ' + JSON.stringify(data)) }) .catch((error) => { console.error('Operation failed. Cause: ' + JSON.stringify(error)); })
1
2
3
4
5
6
7
8
9
10
11
12
13
14运行结果如下所示:
# 7.4.3:小结
本节简单介绍了页面内和页面间的跳转方法以及在跳转过程中的参数传递和取值,另外请读者看一个场景:从不同的页面跳转到B页面,但是B页面需要登录才可以跳转,一般做法是在打开B页面时判断是否登录,如果登录了直接跳转B页面否则跳转登录页面去登录,登录成功后再跳转B页面。以上场景请读者思考一下,能否把类似校验逻辑基于 Router 封装一个更强大的 SuperRouter 出来?笔者也写了一版具有类似功能的 Router ,后续会开源出来,也期待读者能自己动手写一下开源出来,大家一起学习,一起为 OpenHarmony 生态发展贡献力量。