鸿蒙开发中 导航栏Navigation组件的使用

本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新

以下是鸿蒙开发中 Navigation 组件的深度解析,涵盖核心概念、API详解、示例,基于最新文档(API 10+)整理:

一、Navigation 核心架构

1. 组件层级关系

 Navigation --> NavDestination
 Navigation --> NavRouter
 NavDestination --> Page1|Page2|Page3
 NavRouter --> NavStack
2. 核心功能对比
功能NavigationRouterTabs
导航形式堆栈式管理页面跳转底部/顶部栏切换
动画支持内置滑动/渐变动画需自定义
状态保持自动保存页面状态需手动配置保持当前页状态
适用场景线性流程(如注册流)跨模块跳转平级页面切换

二、基础用法与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中取消订阅事件

八、总结

  1. 路由设计原则

    • 浅栈优先(深度≤5)
    • 参数序列化(避免复杂对象)
  2. 性能优化

    • 高频跳转使用NavRouter预加载
    • 大数据传参改用ID查询
  3. 安全规范

// 路由拦截示例
this.navController.addInterceptor((to, from) => {
  if (to.path === 'PayPage' && !isLogin) {
    return { path: 'LoginPage' } // 重定向
  }
  return to
})