第6章 路由和组件导航 路由和组件导航是鸿蒙应用开发中实现页面跳转的两种方式。其中,路由提供了一些方法用于实现页面跳转,组件导航则是通过Navigation组件制作导航页,并为导航页添加子页跳转功能,通过子页跳转实现页面跳转。本章将对路由和组件导航进行详细讲解。6.1 路由6.1.1 页面跳转页面跳转是指从一个页面导航到另一个页面,并且可以将数据从一个页面传递到另一个页面。下面演示一个购物软件的页面跳转过程,如下图所示。在鸿蒙应用中,路由负责管理不同页面之间的跳转和参数传递,它基于轻量级的栈式管理结构,每个页面都有唯一的标识符,所有被访问过的页面都会被放置在页面栈中。每当页面跳转时,路由会根据标识符对页面进行入栈或出栈操作,实现页面跳转和管理。页面栈是一个后进先出的数据结构,用于存储鸿蒙应用中打开的页面。页面栈的顶部始终是当前页,而其他页面则按照它们被打开的顺序排列在下面。页面栈的最大容量为32个页面。若超出此限制,可能会导致应用程序出现异常行为,例如页面无法正常压入页面栈或无法正常返回等。为了避免超出页面栈的最大容量,可以在页面跳转时,选择适当的页面跳转模式。路由功能通过router对象(或称为router模块)来实现,该对象有两种导入方式。第1种导入方式如下。 import router from '@ohos.router';第2种导入方式如下。 import { router } from '@kit.ArkUI';以上两种导入方式的效果相同。router对象提供了pushUrl()方法和replaceUrl()方法,这两个方法都可以实现页面跳转,它们的区别在于目标页是否会替换当前页。方法说明pushUrl()目标页不会替换当前页,而是将当前页压入页面栈以保留当前页的状态,跳转后可以通过返回操作回到当前页。这种模式适用于常规的页面导航,例如从一个列表页跳转到详情页replaceUrl()目标页会替换当前页,当前页会被销毁并释放资源。跳转后无法通过返回操作回到当前页。这种模式适用于需要替换当前页的场景,例如在登录成功后直接跳转到主页pushUrl()方法的基本语法格式如下。 router.pushUrl(options, mode?, callback?);① options参数是一个对象,用于设置目标页的描述信息,该对象有两个属性: url属性表示目标页的路径。 params属性表示传递的参数。如果传递了参数,则在目标页中可以通过调用router对象的getParams()方法来获取传递过来的参数。如果不需要传递参数,可以省略params属性。② mode参数是可选的,用于设置跳转页面使用的模式,包括标准实例模式router.RouterMode.Standard和单实例模式router.RouterMode.Single,它们的区别在于是否会新建目标页,默认使用标准实例模式,两种模式的说明如下表所示。模式说明标准实例模式每次跳转都会新建一个目标页并压入栈顶。这种模式适用于需要在同一URL下展示不同内容或状态的场景,例如博客的不同文章页面单实例模式如果目标页已经在页面栈中,则离栈顶最近的同URL页面会被移动到栈顶并重新加载;如果目标页不存在,则按照标准实例模式跳转。这种模式适用于需要保持页面状态一致性的场景,例如购物软件的商品详情页面③ callback参数是可选的,用于处理成功或失败情况的回调函数。如果省略了mode参数,callback参数可作为第2个参数。注意:跳转的页面必须是被@Entry装饰的组件,并且该页面必须注册到entry/src/main/resources/base/profile/main_page.json文件中。当pushUrl()方法跳转失败时,通常会返回一个错误码,表示跳转失败的具体原因。pushUrl()方法的常见错误码及其说明如下表所示。错误码说明100001内部错误,可能是未成功获取渲染引擎或解析参数失败等原因导致的。需要检查代码逻辑或参数设置,确保跳转操作能正确执行100002路由页面跳转时输入的路径错误或不存在。需要确保跳转的目标页路径正确,并且在路由配置中正确注册了该页面100003跳转页面压入页面数量超过32。在这种情况下,可以考虑优化页面导航逻辑,减少页面数量replaceUrl()方法与pushUrl()方法的参数相同,两者接收相同的参数格式。当replaceUrl()方法跳转失败时,通常会返回一个错误码,表示跳转失败的具体原因。replaceUrl()方法的常见错误码及其说明如下表所示。错误码说明100001内部错误,可能是未成功获取渲染引擎或解析参数失败等原因导致的。需要检查代码逻辑或参数设置,确保跳转操作正确执行200002路由页面替换时输入的路径错误或不存在。需要确保跳转的目标页路径正确,并且在路由配置中正确注册了该页面下面演示如何使用pushUrl()方法实现页面跳转并传递参数以及处理错误。import { router } from '@kit.ArkUI'; interface Student { name: string; } @Entry @Component struct FirstPage { build() { Column(){ Text('第一页') Button('跳转下一页') .margin({ top: 50 }) .onClick(() = { router.pushUrl( { url: 'pages/SecondPage', params: { id: 1 } }, err = { if (err) { console.log(`路由失败,errcode: ${err.code} errMsg: ${err.message}`); } } ) }) Button('获取参数') .margin({ top: 50 }) .onClick(() = { const params = router.getParams() as Student; if (params) { AlertDialog.show({ message: `${params.name}` }) } }) } .width('100%') .height('100%') } }import { router } from '@kit.ArkUI'; import { promptAction } from '@kit.ArkUI'; interface Person { id: number; } @Entry @Component struct SecondPage { build() { Column() { Text('第二页') Button('获取参数') .margin({ top: 50 }) .onClick(() = { const params = router.getParams() as Person; if (params) { AlertDialog.show({ message: `${params.id}` }); } }) Button('返回上一页') .margin({ top: 50 }) .onClick(() = { router.back({ url: 'pages/FirstPage', params: { name: '张三' } }); }) ​ Button('退出') .onClick(() = { router.showAlertBeforeBackPage({ message: '确认要放弃付款吗?' }); router.back(); }) ​ Button('退出') .margin({ top: 50 }) .onClick(() = { promptAction.showDialog({ message: '确认要放弃付款吗?', buttons: [ { text: '取消', color: '#F00' }, { text: '