HarmonyOS鸿蒙Next中【ArkUI路由/导航系列】二:Navigation基础路由操作,让页面跳转起来
HarmonyOS鸿蒙Next中【ArkUI路由/导航系列】二:Navigation基础路由操作,让页面跳转起来 在这篇文章中,将逐步的介绍,如何通过Navigation进行页面间的切换。
1、页面跳转的准备工作
首先,开发者需要创建一个NavPathStack对象并作为构造入参传给Navigation组件,以实现二者的绑定,后续的路由操作均基于该NavPathStack展开。
// BasicNavigation.ets
@Component
struct BasicNavigation {
stack: NavPathStack = new NavPathStack()
build() {
// 将导航控制器NavPathStack 绑定至Navigation中。
Navigation(this.stack) {
// Navigation作为路由根容器,可以不显示任何内容
}
}
}
此时我们已经构建好了一个Navigation根容器并绑定了导航控制器NavPathStack,接下来我们需要构建显示的页面。
Step1、构建子页面
为每个NavDestination声明对外的实例化方法,如代码中的PageOneBuilder,执行该方法会创建一个BasicNavDestination的自定义组件,该组件就是一个Navigation的子页面。
// BasicNavDest.ets
// 组件实例化方法,该方法会创建BasicNavDestination自定义组件作为Navigation的页面
@Builder
export function PageOneBuilder() {
BasicNavDestination({
name: 'pageOne'
});
}
// NavDestination组件
@Component
struct BasicNavDestination {
name: string = 'NA'
build() {
NavDestination() {
// 页面中的内容
}
}
}
Step2、配置Navigation路由表
将步骤一中写好的实例化方法与它的name(开发者自定义)写在路由表的配置文件中(entry/src/main/resources/base/profile/route_map.json开发者自行创建)。
// entry/src/main/resources/base/profile/route_map.json
{
"routerMap": [
{
"name": "basicPageOne", // 路由页面的唯一标识符
"pageSourceFile": "src/main/ets/pages/BasicFeature/BasicNavDest.ets", // 源码所在地址
"buildFunction": "PageOneBuilder", // 页面的实例化方法名称
},
]
}
Step3、使能Navigation路由表
将步骤二中创建的route_map.json配置为系统路由表。开发者需要在当前模块的module.json5中,为“module”的内容新增一个配置项,例如:
{
"module": {
"name": "entry",
"type": "entry",
"description": "$string:module_desc",
"mainElement": "EntryAbility",
"deviceTypes": [
"phone"
],
"pages": "$profile:main_pages",
"routerMap": "$profile:route_map", // 新增这一行,使能路由表
"abilities": [...]
}
}
2、NavPathStack的获取
Navigation根容器和子页面以及路由表配置完成后,即可通过调用NavPathStack的api来实现页面之间的跳转。以下通过按钮点击来触发路由操作:
Button('跳转到basicPageOne')
.width(330)
.margin(7)
.onClick(() => {
this.stack.pushPath({name: 'basicPageOne'})
})
对于没有分栏诉求的应用,推荐将Navigation的导航栏NavBar隐藏,基于NavDestination组件进行所有页面功能的开发,例如:
// BasicNavigation.ets
@Component
struct BasicNavigation {
stack: NavPathStack = new NavPathStack()
aboutToAppear(): void {
// 2.将basicPageOne作为Navigation的首页显示
this.stack.pushPath({name: 'basicPageOne'})
}
build() {
Navigation(this.stack) {
// Navigation作为路由根容器,可以不显示任何内容
}
// 1. 将Navigation导航栏NavBar进行隐藏
.hideNavBar(true)
}
}
这样一来,所有的操作均会基于NavDestination组件展开,开发者可以将导航控制器对象NavPathStack存在全局的AppStorage中,方便后续在其他NavDestination中的路由控制:
// BasicNavigation.ets
@Component
struct BasicNavigation {
stack: NavPathStack = new NavPathStack()
aboutToAppear(): void {
// 1.将当前导航控制器对象存储至AppStorage中,可以在同应用内的任意地方获取
AppStorage.setOrCreate<NavPathStack>('basicNavigationStack', this.stack)
this.stack.pushPath({name: 'basicPageOne'})
}
build() {
Navigation(this.stack) {
// Navigation作为路由根容器,可以不显示任何内容
}
.hideNavBar(true)
}
}
此外,还有其他的获取NavPathStack的方式,参见系列后续章节。
3、路由操作方法
navigation框架有三种主要的路由操作:push、pop、replace,下文会分别介绍。
3.1 Push
push操作用以创建一个新的页面视图。主要分为两种,带有异步返回结果的pushDestination和不带返回结果的pushPath。
如果push过程发生了错误,pushPath会跳转到一个空白的页面,pushDestination则会将该错误携带错误码返回给开发者。相应的,如果跳转成功,pushDestination会将成功的结果返回给开发者。示例如下:
// BasicNavDest.ets
Button('pushDestination跳转basicPageOne')
.width(330)
.margin(7)
.onClick(() => {
// pushDestination会带有异步结果返回
this.stack.pushDestination({name: 'basicPageOne'})
.then(() => {
// .then分支表明本次跳转成功,没有发生错误
console.log('AceNavigation', 'pushDestination跳转basicPageOne', 'success!')
})
.catch((err: Object) => {
// .catch分支表明本次跳转失败,错误信息包含在入参err中
console.log('AceNavigation', 'pushDestination跳转basicPageOne', 'failed!')
console.log('AceNavigation', '-- err info: ' + JSON.stringify(err))
})
})
Button('pushPath跳转basicPageOne')
.width(330)
.margin(7)
.onClick(() => {
// pushPath不带有返回结果
this.stack.pushPath({name: 'basicPageOne'})
})
除了是否返回结果外,pushPath与pushDestination在用法上没有区别。开发者还可以通过传入NavigationOptions参数来控制本次push的行为,例如,实现一个单实例跳转、无动画跳转:
// BasicNavDest.ets
Button('单实例、无动画跳转basicPageOne')
.width(330)
.margin(7)
.onClick(() => {
// 指定launchMode为MOVE_TO_TOP_SINGLETON,会复用Index最大的同名页面;指定animated为false则会禁用本次跳转的动画。
this.stack.pushPath({name: 'basicPageOne'}, {launchMode: LaunchMode.MOVE_TO_TOP_SINGLETON, animated: false})
})
3.2 Pop
pop操作用以删除Navigation导航栈顶页面,可以传入参数来控制是否禁用动画。例如:
// BasicNavDest.ets
Button('Pop有动画pop')
.width(330)
.margin(7)
.onClick(() => {
// 接口无参数传递时默认有动画
this.stack.pop()
})
Button('Pop无动画pop')
.width(330)
.margin(7)
.onClick(() => {
// 传递animated参数为false时,本次操作会禁用动画
this.stack.pop(false)
})
3.3 Replace
replace操作会用一个新的页面替换当前NavPathStack栈顶页面,如下示例:
// BasicNavDest.ets
Button('replace跳转basicPageOne')
.width(330)
.margin(7)
.onClick(() => {
// 使用basicPageOne替换当前栈顶页面
this.stack.replacePath({name: 'basicPageOne'})
})
Button('replace跳转basicPageTwo')
.width(330)
.margin(7)
.onClick(() => {
// 使用basicPageTwo替换当前栈顶页面。basicPageTwo上文示例中没有创建,请参照basicPageOne自行实现。
this.stack.replacePath({name: 'basicPageTwo'})
})
2.1.3章节的动画示例分别如下(push&&pop、replace):
(未完待续……)
更多关于HarmonyOS鸿蒙Next中【ArkUI路由/导航系列】二:Navigation基础路由操作,让页面跳转起来的实战教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next的ArkUI中,Navigation组件实现基础路由跳转需使用Router模块。关键步骤如下:
- 配置路由路径: 在entry/src/main/resources/base/profile/main_pages.json定义路由页面路径,如:
{
"src": [
"pages/Index",
"pages/Detail"
]
}
- 页面跳转方法:
- 使用router.pushUrl()进行页面推入:
router.pushUrl({
url: 'pages/Detail'
})
- 使用router.back()返回上一页
- 参数传递: 通过params对象传递参数:
router.pushUrl({
url: 'pages/Detail',
params: { id: 123 }
})
接收方使用router.getParams()获取参数。
更多关于HarmonyOS鸿蒙Next中【ArkUI路由/导航系列】二:Navigation基础路由操作,让页面跳转起来的实战系列教程也可以访问 https://www.itying.com/category-93-b0.html
在HarmonyOS Next中,Navigation组件配合NavPathStack提供了强大的路由管理能力。您已经详细介绍了基础配置和三种核心路由操作:
-
基础配置要点:
- 必须创建NavPathStack并与Navigation绑定
- 通过@Builder构建子页面组件
- 路由表配置在route_map.json中
- 需要在module.json5中启用路由表
-
路由操作对比:
- Push操作:
- pushPath:简单跳转,无返回结果
- pushDestination:支持Promise,可捕获错误
- 支持NavigationOptions参数控制跳转行为
- Push操作:
-
实际开发建议:
- 对于无分栏需求的应用,建议隐藏NavBar(hideNavBar(true))
- 将NavPathStack存入AppStorage便于全局访问
- 合理使用launchMode控制页面实例化方式
您提供的代码示例已经非常完整,特别是关于路由表配置和三种路由操作的实现。需要注意的是,replace操作会销毁当前页面实例,适合登录页跳转主页等场景。
动画控制方面,通过animated参数可以灵活控制转场效果,这对提升用户体验很重要。
后续可以继续探讨:
- 路由传参的实现方式
- 复杂场景下的路由管理
- 页面生命周期与路由的关系
- 自定义转场动画等高级特性