HarmonyOS应用开发实战:猫猫大作战-Navigation 的核心架构、NavBar 与 NavDestination 的协作方式、与 router
·


前言
在 HarmonyOS 路由体系中,Navigation 组件是官方推荐的新一代导航方案。与传统的 router 相比,Navigation 提供了更强大的页面栈管理、更灵活的分栏布局、更完善的路由拦截能力。从 API 12 开始,官方逐步推荐使用 Navigation 替代 router,并在后续版本中持续增强其能力。
本文以「猫猫大作战」从 router 迁移到 Navigation 的实战为锚点,讲解 Navigation 的核心架构、NavBar 与 NavDestination 的协作方式、与 router 的对比迁移路径。
提示:本系列不讲 ArkTS 基础语法与环境搭建,假设你已跟完第 1–81 篇。本篇是阶段三第 82 篇。
一、Navigation 核心架构
1.1 三大核心概念
Navigation(导航根容器)
│
├── NavBar(导航栏 / 主页)
│ ├── 标题栏
│ ├── 菜单栏
│ └── 内容区
│
└── NavDestination(子页面容器)
├── 标题栏
├── 内容区
└── 工具栏
| 组件 | 角色 | 说明 |
|---|---|---|
| Navigation | 根容器 | 包裹所有导航页面,提供分栏能力 |
| NavBar | 导航主页 | 应用中始终存在的页面(类似 Tab 主页) |
| NavDestination | 目标页面 | 路由跳转的目标页容器 |
1.2 基础使用
@Entry
@Component
struct AppNavigation {
private stack: NavPathStack = new NavPathStack();
build() {
Navigation(this.stack) {
// NavBar 内容 — 主菜单
Column() {
Text('🐱 猫猫大作战')
.fontSize(36)
.fontWeight(FontWeight.Bold)
Button('开始游戏')
.onClick(() => {
this.stack.pushPath({ name: 'pages/GameBoard' });
})
Button('🏆 排行榜')
.onClick(() => {
this.stack.pushPath({ name: 'pages/Leaderboard' });
})
}
}
.title('主菜单')
.navBarWidth('100%')
}
}
二、Navigation 与 router 对比
2.1 核心差异
| 对比维度 | router | Navigation |
|---|---|---|
| 组件类型 | API 函数 | 声明式组件 |
| 页面容器 | 系统管理页面栈 | NavPathStack 显式管理 |
| 分栏模式 | 不支持 | 支持 Split 单栏/分栏 |
| 路由拦截 | 不支持 | setInterception |
| 生命周期 | 系统自动管理 | 组件树自然管理 |
| 参数传递 | params: Object | param: Object |
| 返回结果 | forResult(API 23+) | 原生支持 |
| TS/JS 语法 | 函数式 | 声明式 |
| 推荐度 | 旧方案 | 官方推荐 |
2.2 代码对比
// router 方式
import { router } from '@kit.ArkUI';
router.pushUrl({
url: 'pages/Detail',
params: { id: 1001 }
});
// Navigation 方式
stack.pushPath({
name: 'pages/Detail',
param: { id: 1001 }
});
三、NavPathStack 路由栈
3.1 创建与绑定
@Entry
@Component
struct GameApp {
// 创建路由栈管理器
private navStack: NavPathStack = new NavPathStack();
build() {
// 绑定到 Navigation 容器
Navigation(this.navStack) {
this.NavBar()
}
}
}
3.2 核心方法
| 方法 | 说明 | 对应 router |
|---|---|---|
pushPath(info) |
压入新页面 | router.pushUrl |
replacePath(info) |
替换当前页面 | router.replaceUrl |
pop() |
弹出当前页面 | router.back |
popToName(name) |
弹出到指定页面 | router.back({ url }) |
popToIndex(index) |
弹出到指定索引 | — |
clear() |
清空路由栈 | router.clear |
getAllPathName() |
获取所有页面名 | router.getState |
四、NavDestination 目标页
4.1 注册式导航
Navigation 使用 navDestination 的 @Builder 注册页面:
@Entry
@Component
struct GameApp {
private stack: NavPathStack = new NavPathStack();
build() {
Navigation(this.stack) {
this.NavBar()
}
.navDestination(this.navDestBuilder) // 注册页面构建器
}
// 页面构建器 — 根据 name 返回对应页面
@Builder
navDestBuilder(name: string, param: Object) {
if (name === 'pages/GameBoard') {
GameBoard({ param: param })
} else if (name === 'pages/Leaderboard') {
Leaderboard({ param: param })
}
}
}
@Component
struct GameBoard {
@State param: Object = {};
build() {
NavDestination() {
Text('游戏棋盘页面')
}
.title('游戏进行中')
}
}
@Component
struct Leaderboard {
@State param: Object = {};
build() {
NavDestination() {
Text('排行榜页面')
}
.title('高分榜')
}
}
4.2 NavDestination 结构
NavDestination() {
// 内容区
Column() {
Text('页面内容')
}
}
.title('标题') // 标题栏
.menu(this.MenuBuilder) // 菜单栏
.toolBar(this.ToolBarBuilder) // 工具栏
.backButtonIcon($r('sys.media.ohos_ic_back')) // 自定义返回图标
.hideTitleBar(false) // 隐藏标题栏
五、参数传递
5.1 传递参数
// 发送方
this.stack.pushPath({
name: 'pages/Leaderboard',
param: {
fromPage: 'main_menu',
highScore: 88888
}
});
5.2 接收参数
@Component
struct Leaderboard {
@State highScore: number = 0;
@State fromPage: string = '';
aboutToAppear() {
// 通过 NavPathStack 获取参数
// 在当前组件中可以通过 @State param 接收
}
}
六、获取当前路由信息
// 获取页面栈信息
const pathNames = this.stack.getAllPathName();
// ['pages/Index', 'pages/Leaderboard', 'pages/Detail']
const index = this.stack.getIndexByName('pages/Leaderboard');
// 返回 1
const currentName = this.stack.getCurrentName();
// 'pages/Detail'
const size = this.stack.size();
// 3
七、从 router 迁移到 Navigation
7.1 迁移步骤
步骤 1:将根组件改为 Navigation + NavPathStack
步骤 2:将 router.pushUrl → stack.pushPath
步骤 3:将 router.replaceUrl → stack.replacePath
步骤 4:将 router.back → stack.pop
步骤 5:将 router.getParams → navDestination 的 param 参数
步骤 6:注册 navDestination @Builder
7.2 迁移示例
// 迁移前:router
import { router } from '@kit.ArkUI';
router.pushUrl({ url: 'pages/Detail', params: { id: 1 } });
// 迁移后:Navigation
this.stack.pushPath({ name: 'pages/Detail', param: { id: 1 } });
// router.back({ url: 'pages/Index' })
this.stack.popToName('pages/Index');
八、总结
Navigation 是 HarmonyOS 路由体系的官方推荐方案,提供了声明式的页面管理、灵活的 NavPathStack 路由栈、Split 分栏模式等 router 不具备的能力。
核心要点:
- Navigation 是声明式路由容器,NavPathStack 管理页面栈
- NavBar 为主页,NavDestination 为目标页
- 通过 navDestination @Builder 注册"路由表"
- pushPath/pop/clear 对应 router 的 pushUrl/back/clear
- 官方推荐从 router 迁移到 Navigation
下一篇预告:第 83 篇将深入 NavPathStack 的完整 API——pushPath、replacePath、popToName、clear 等核心方法详解。
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源:
更多推荐


所有评论(0)