HarmonyOS Navigation 实战:NavPathStack 跳转、传参、返回和路由表一次讲清
系列:HarmonyOS 开发入门 · 08
上一篇解决“为什么选 Navigation”,这一篇直接把一套能用于真实项目的基础结构搭起来。
目标很简单:
首页 -> 详情页 -> 返回
并且把参数一起传过去。
1. 创建根 Navigation
@Entry
@Component
struct Index {
private pathStack: NavPathStack = new NavPathStack()
build() {
Navigation(this.pathStack) {
Column({ space: 20 }) {
Text('首页')
.fontSize(30)
.fontWeight(FontWeight.Bold)
Button('查看商品 1001')
.onClick(() => {
this.pathStack.pushPath({
name: 'DetailPage',
param: { productId: 1001 }
})
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
.hideTitleBar(true)
}
}
NavPathStack 是这套导航的核心控制器。
2. 创建 DetailPage
DetailPage.ets:
@Builder
export function DetailPageBuilder() {
DetailPage()
}
@Component
struct DetailPage {
private pathStack: NavPathStack = new NavPathStack()
private productId: number = 0
build() {
NavDestination() {
Column({ space: 20 }) {
Text(`商品 ID:${this.productId}`)
.fontSize(24)
Button('返回')
.onClick(() => {
this.pathStack.pop()
})
}
.width('100%')
.height('100%')
.justifyContent(FlexAlign.Center)
}
.title('商品详情')
.onReady((context: NavDestinationContext) => {
this.pathStack = context.pathStack
const param = context.pathInfo.param as Record<string, number>
this.productId = param?.productId ?? 0
})
}
}
这里有两个重点:
NavDestination才是 Navigation 子页面的根容器;- 子页面可以在
onReady获取当前pathStack和参数。
实际项目里建议给参数定义明确类型,不要长期用 Record 顶着。
3. 配置系统路由表
在:
entry/src/main/resources/base/profile/
创建:
router_map.json
内容:
{
"routerMap": [
{
"name": "DetailPage",
"pageSourceFile": "src/main/ets/pages/DetailPage.ets",
"buildFunction": "DetailPageBuilder"
}
]
}
然后在 module.json5 的 module 节点注册:
"routerMap": "$profile:router_map"
做到这里,页面名称和页面实现就关联起来了。
4. 常用栈操作
push
this.pathStack.pushPath({ name: 'DetailPage' })
pop
this.pathStack.pop()
replace
某些场景不希望用户再回到当前页,可以使用替换语义:
this.pathStack.replacePath({ name: 'HomePage' })
比如登录完成后把登录页替换掉,就很常见。
5. 参数不要传得太重
页面跳转时传:
{
productId: 1001
}
通常比直接把一个复杂业务对象全部塞进去更稳。
原因很简单:详情页真正需要的是“找到这条数据的标识”,而不是强依赖上一个页面当时那份对象快照。
当然,小型临时对象也可以传,具体看业务。
6. NavPathStack 放在哪里
小 Demo 可以直接放首页。
项目变大后,要考虑统一管理,例如通过 AppStorage、Provider 或自己的路由管理器把导航栈提供给业务层。
但我不建议一上来就造一个几百行“超级 RouterManager”。
先把官方 Navigation 的能力用明白,再做封装。
7. 页面生命周期也随之变化
使用 Navigation 后,页面真正的显示语义在 NavDestination 上。
因此做页面曝光、返回刷新、页面隐藏等逻辑时,要优先理解 NavDestination 生命周期,而不是把旧的 router 页面生命周期直接照搬过来。
8. 一个工程化的小改进
把页面名集中:
export class RouteName {
static readonly DETAIL: string = 'DetailPage'
}
调用:
this.pathStack.pushPath({
name: RouteName.DETAIL,
param: { productId: 1001 }
})
以后改名称、做全局搜索都会轻松很多。
总结
Navigation 入门真正需要掌握的是四个东西:
Navigation
NavDestination
NavPathStack
router_map.json
把这四个串起来,页面跳转就从“能用”进入“可以做工程”。
下一篇开始接系统能力,先从每个 App 几乎都绕不开的 HTTP 网络请求开始。
更多推荐



所有评论(0)