本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
以下是鸿蒙开发中 Navigation 组件的深度解析,涵盖核心概念、API详解、示例,基于最新文档(API 10+)整理:
一、Navigation 核心架构
1. 组件层级关系
Navigation --> NavDestination
Navigation --> NavRouter
NavDestination --> Page1|Page2|Page3
NavRouter --> NavStack
2. 核心功能对比
功能 | Navigation | Router | Tabs |
---|---|---|---|
导航形式 | 堆栈式管理 | 页面跳转 | 底部/顶部栏切换 |
动画支持 | 内置滑动/渐变动画 | 需自定义 | 无 |
状态保持 | 自动保存页面状态 | 需手动配置 | 保持当前页状态 |
适用场景 | 线性流程(如注册流) | 跨模块跳转 | 平级页面切换 |
二、基础用法与API详解
1. 基本结构
@Entry
@Component
struct App {
private navController: NavigationController = new NavigationController()
build() {
Navigation(this.navController) {
NavDestination() {
HomePage() // 默认首页
}.title('首页')
NavDestination() {
DetailPage()
}.title('详情页')
}
.title('主导航')
.navBarWidth('50%') // 导航栏宽度
}
}
2. 核心API
API分类 | 方法/属性 | 说明 |
---|---|---|
导航控制 | push() / pop() | 入栈/出栈操作 |
popTo() | 返回到指定页面 | |
状态获取 | getCurrentRoute() | 获取当前路由信息(含参数) |
样式定制 | .navBarHeight() | 设置导航栏高度 |
.hideNavBar() | 隐藏导航栏(全屏模式) | |
动画控制 | .transition() | 设置页面切换动画(Push/Pop) |
三、示例
1. 带参数的页面跳转
// 跳转传参
this.navController.push({
path: 'DetailPage',
params: { id: 123 } // 参数对象
})
// 目标页接收参数
@Component
struct DetailPage {
@State id: number = 0
onPageShow() {
const route = this.navController.getCurrentRoute()
this.id = route.params?.id || 0
}
}
2. 自定义导航栏
Navigation(this.navController) {
NavDestination() {
HomePage()
}
.title('首页')
.navBar(this.buildCustomNavBar()) // 自定义导航栏
}
@Builder
buildCustomNavBar() {
Row() {
Image($r('app.media.back'))
.onClick(() => this.navController.pop())
Text('自定义标题').margin({ left: 10 })
}
}
3. 嵌套导航
Navigation(this.navController) {
NavDestination() {
// 第一级导航
Navigation(new NavigationController()) {
NavDestination() { SubPage1() }
NavDestination() { SubPage2() }
}
}
}
四、动画与过渡效果
1. 内置动画类型
.transition({
type: RouteType.Push,
curve: Curve.EaseOut,
duration: 300,
// API 10+ 新增效果
enterEffect: SharedTransitionEffect.OPACITY,
exitEffect: SharedTransitionEffect.SCALE
})
2. 共享元素动画
// 页面A(共享元素标记)
Image($r('app.media.avatar'))
.sharedTransition('avatar')
// 页面B(相同标识符)
Image($r('app.media.avatar'))
.sharedTransition('avatar')
五、状态管理与性能优化
1. 页面状态保持
NavDestination() {
UserCenterPage()
}
.statePreservation(true) // 开启状态缓存
2. 懒加载优化
NavDestination() {
LazyComponent(() => HeavyPage()) // 延迟加载
}
3. 导航栈监控
this.navController.addStackChangeListener((routes) => {
console.log(`当前栈深度: ${routes.length}`)
})
六、完整流程示例
@Entry
@Component
struct ShoppingFlow {
private navController: NavigationController = new NavigationController()
build() {
Navigation(this.navController) {
NavDestination() {
ProductListPage({
onItemClick: (id) => {
this.navController.push({
path: 'DetailPage',
params: { id }
})
}
})
}
NavDestination() {
ProductDetailPage()
}
NavDestination() {
CheckoutPage({
onBack: () => this.navController.popTo('ProductListPage')
})
}
}
.transition({
type: RouteType.Push,
effect: SharedTransitionEffect.SLIDE_RIGHT
})
}
}
七、调试与常见问题
1. 导航栈可视化
// 打印当前导航栈
console.log(JSON.stringify(
this.navController.getRoutes(),
null, 2
))
2. 常见错误处理
错误场景 | 解决方案 |
---|---|
重复push相同页面 | 检查路由路径是否唯一,或用popTo() 替代 |
参数丢失 | 使用onPageShow 生命周期确保参数加载完成 |
动画卡顿 | 减少共享元素数量,避免复杂页面过渡 |
内存泄漏 | 在onPageHide 中取消订阅事件 |
八、总结
-
路由设计原则
- 浅栈优先(深度≤5)
- 参数序列化(避免复杂对象)
-
性能优化
- 高频跳转使用
NavRouter
预加载 - 大数据传参改用ID查询
- 高频跳转使用
-
安全规范
// 路由拦截示例
this.navController.addInterceptor((to, from) => {
if (to.path === 'PayPage' && !isLogin) {
return { path: 'LoginPage' } // 重定向
}
return to
})