页面路由(@ohos.router)
页面路由指在应用程序中实现不同页面之间的跳转和数据传递。Router
模块通过不同的url地址,可以方便地进行页面路由,轻松地访问不同的页面。本文将从页面跳转、页面返回、页面返回前增加一个询问框和命名路由几个方面介绍Router
模块提供的功能。
页面跳转与参数接收
页面跳转
页面跳转是开发过程中的一个重要组成部分。在使用应用程序时,通常需要在不同的页面之间跳转,有时还需要将数据从一个页面传递到另一个页面。
方法 | router.pushUrl() | router.replaceUrl() |
---|---|---|
用途 | 用于添加新页面到页面栈,保留原有页面。 | 用于替换当前页面,将目标页面URL替代为当前页面URL。 |
参数 | 接受目标页面URL和导航模式参数。 | 接受目标页面URL和导航模式参数。 |
页面栈变化 | 如果目标页面的URL已存在于页面栈中,会增加页面栈的元素数量。 | 如果目标页面的URL已存在于页面栈中,会减少页面栈的元素数量。 |
行为 | 创建新页面并添加到页面栈,保留原有页面。 | 移动现有页面到栈顶,替换当前页面,销毁被替换的当前页面。 |
导航模式 | 通常支持 “Single” 和 “Standard” 模式。 | 通常支持 “Single” 和 “Standard” 模式。 |
使用场景 | 用于常规页面切换,保留原有页面状态。 | 用于特殊场景,如页面替换和销毁。 |
特征 | router.pushUrl() | router.replaceUrl() |
---|---|---|
导航模式 | 通常支持 “Single” 和 “Standard” 模式。 | 通常支持 “Single” 和 “Standard” 模式。 |
“Single” 行为 | - 如果目标页面的URL已存在于页面栈中,会增加页面栈的元素数量。 - 最近的相同URL页面会被移动到栈顶,成为新建页。 - 原来的页面仍然存在于栈中,页面栈的元素数量不变。 | - 如果目标页面的URL已存在于页面栈中,会减少页面栈的元素数量。 - 移动现有页面到栈顶,替换当前页面,销毁被替换的当前页面。 |
“Standard” 行为 | - 无论目标页面的URL在页面栈中是否存在相同的URL页面,会按照多实例模式进行导航。 - 页面栈的元素数量保持不变。 | - 无论目标页面的URL在页面栈中是否存在相同的URL页面,会按照多实例模式进行导航。 - 页面栈的元素数量保持不变。 |
router.pushUrl({ url: 'pages/Second', params: { src: 'Index页面传来的数据', } }, router.RouterMode.Single) router.replaceUrl({ url: 'pages/Second', params: { src: 'Index页面传来的数据', } }, router.RouterMode.Single)
参数接收
通过调用router.getParams()
方法获取Index页面传递过来的自定义参数
import router from '@ohos.router'; @Entry @Component struct Second { @State src: string = router.getParams()?.['src']; // 页面刷新展示 ... }
页面返回
页面返回
当用户在一个页面完成操作后,通常需要返回到上一个页面或者指定页面,这就需要用到页面返回功能。在返回的过程中,可能需要将数据传递给目标页面,这就需要用到数据传递功能。
在Second
页面中,可以通过调用router.back()
方法实现返回到上一个页面,或者在调用router.back()
方法时增加可选的options
参数(增加url参数)返回到指定页面,也可以返回命名路由页面。
import router from '@ohos.router'; // 返回上级 router.back(); // 返回制定页面 router.back({ url: 'pages/Index' }); // myPage为返回的命名路由页面别名 router.back({ url: 'myPage' });
页面返回询问对话框
在开发应用时,为了避免用户误操作或者丢失数据,有时候需要在用户从一个页面返回到另一个页面之前,弹出一个询问框,让用户确认是否要执行这个操作。
启用页面返回询问对话框功能:
使用 router.enableBackPageAlert() 方法开启页面返回询问对话框功能。这个功能只针对当前页面生效。在调用 router.pushUrl() 或 router.replaceUrl() 方法后,跳转到的新页面被视为新建页面,因此在页面返回之前需要先调用 router.enableBackPageAlert() 方法,以启用页面返回询问对话框功能。
router.enableBackPageAlert({ message: 'Message Info' }); router.back();
关闭页面返回询问对话框功能:
如果需要关闭页面返回询问对话框功能,可以使用 router.disableAlertBeforeBackPage() 方法。这个方法用于在特定情况下禁用询问对话框,以确保在页面返回时不会出现确认提示。
自定义询问框
自定义询问框的方式,可以使用弹窗或者自定义弹窗实现。这样可以让应用界面与系统默认询问框有所区别,提高应用的用户体验度。
import router from '@ohos.router'; import promptAction from '@ohos.promptAction'; import { BusinessError } from '@ohos.base'; function onBackClick() { // 弹出自定义的询问框 promptAction.showDialog({ message: '您还没有完成支付,确定要返回吗?', buttons: [ { text: '取消', color: '#FF0000' }, { text: '确认', color: '#0099FF' } ] }).then((result:promptAction.ShowDialogSuccessResponse) => { if (result.index === 0) { // 用户点击了“取消”按钮 console.info('User canceled the operation.'); } else if (result.index === 1) { // 用户点击了“确认”按钮 console.info('User confirmed the operation.'); // 调用router.back()方法,返回上一个页面 router.back(); } }).catch((err:Error) => { let message = (err as BusinessError).message let code = (err as BusinessError).code console.error(`Invoke showDialog failed, code is ${code}, message is ${message}`); }) }
参数接收
在Second页面中,调用router.back()方法返回上一个页面或者返回指定页面时,根据需要继续增加自定义参数,例如在返回时增加一个自定义参数src。
router.back({ url: 'pages/Index', params: { src: 'Second页面传来的数据', } })
从Second页面返回到Index页面。在Index页面通过调用router.getParams()方法,获取Second页面传递过来的自定义参数。
在调用 router.back()
方法时,不会新建页面,而是返回到原来的页面。在原来页面中使用 @State
声明的变量不会重复声明,也不会触发页面的 aboutToAppear()
生命周期回调。因此,不能直接在变量声明以及页面的 aboutToAppear()
生命周期回调中接收和解析 router.back()
传递过来的自定义参数。
这意味着当使用 router.back()
返回到前一个页面时,需要采取其他方式来传递和处理自定义参数,因为原页面的状态和生命周期不会重新初始化。
可以放在业务需要的位置进行参数解析。示例代码在Index页面中的onPageShow()生命周期回调中进行参数的解析。
import router from '@ohos.router'; @Entry @Component struct Index { @State src: string = ''; onPageShow() { this.src = router.getParams()?.['src']; } // 页面刷新展示 ... }
命名路由
在开发中为了跳转到共享包Har
或者Hsp
中的页面(即共享包中路由跳转),可以使用router.pushNamedRoute()
来实现。
在想要跳转到的共享包Har或者Hsp页面里,给@Entry修饰的自定义组件命名:
// library/src/main/ets/pages/Index.ets // library为新建共享包自定义的名字 @Entry({ routeName: 'myPage' }) @Component export struct MyComponent { build() { Row() { Column() { Text('Library Page') .fontSize(50) .fontWeight(FontWeight.Bold) } .width('100%') } .height('100%') } }
配置成功后需要在跳转的页面中引入命名路由的页面:
import router from '@ohos.router'; import { BusinessError } from '@ohos.base'; import('@ohos/library/src/main/ets/pages/Index'); // 引入共享包中的命名路由页面 @Entry @Component struct Index { build() { Flex({ direction: FlexDirection.Column, alignItems: ItemAlign.Center, justifyContent: FlexAlign.Center }) { Text('Hello World') .fontSize(50) .fontWeight(FontWeight.Bold) .margin({ top: 20 }) .backgroundColor('#ccc') .onClick(() => { // 点击跳转到其他共享包中的页面 try { router.pushNamedRoute({ name: 'myPage', params: { data1: 'message', data2: { data3: [123, 456, 789] } } }) } catch (err) { let message = (err as BusinessError).message let code = (err as BusinessError).code console.error(`pushNamedRoute failed, code is ${code}, message is ${message}`); } }) } .width('100%') .height('100%') } }
在当前应用包的oh-package.json5文件中配置依赖。
"dependencies": { "@ohos/library": "file:../library", ... }