HarmonyOS应用开发实战:猫猫大作战-navDestination @Builder 的注册机制、严格模式要求、跨模块页面注册以及代码组织的最佳实践
·


前言
Navigation 路由体系的核心设计之一是注册式跳转——所有可能跳转的目标页都通过 navDestination 的 @Builder 统一注册在 Navigation 组件中。这种模式让路由关系一目了然,也支持严格模式下的编译期检查。
本文以「猫猫大作战」的 Navigation 页面系统为锚点,讲解 navDestination @Builder 的注册机制、严格模式要求、跨模块页面注册以及代码组织的最佳实践。
提示:本系列不讲 ArkTS 基础语法与环境搭建,假设你已跟完第 1–84 篇。本篇是阶段三第 85 篇。
一、navDestination @Builder 注册
1.1 基本注册模式
@Entry
@Component
struct GameApp {
private navStack: NavPathStack = new NavPathStack();
build() {
Navigation(this.navStack) {
this.MainMenu()
}
.navDestination(this.pageBuilder) // ← 注册页面构建器
}
// 页面构建器 — 根据 name 返回对应页面
@Builder
pageBuilder(name: string, param: Object) {
if (name === 'pages/Index') {
IndexPage({ param: param })
} else if (name === 'pages/Leaderboard') {
LeaderboardPage({ param: param })
} else if (name === 'pages/Settings') {
SettingsPage({ param: param })
}
}
@Builder
MainMenu() {
Column() {
Button('排行榜')
.onClick(() => {
this.navStack.pushPath({ name: 'pages/Leaderboard', param: { from: 'menu' } })
})
}
}
}
1.2 工作流程
用户点击"排行榜"按钮
↓
navStack.pushPath({ name: 'pages/Leaderboard' })
↓
Navigation 收到 pushPath 请求
↓
调用 pageBuilder('pages/Leaderboard', param)
↓
pageBuilder 匹配 name 返回 LeaderboardPage 组件
↓
NavDestination 渲染到屏幕上
二、严格模式要求
2.1 严格模式
从 API 12 开始,Navigation 支持 strictMode(严格模式)。开启后,pushPath 调用的 name 必须在 navDestination 中被显式注册:
Navigation(this.navStack) {
// NavBar 内容
}
.navDestination(this.pageBuilder)
.enableStrictMode(true) // 开启严格模式
严格模式下的规则:
| 行为 | 非严格模式 | 严格模式 |
|---|---|---|
| 未注册的 name | 运行时崩溃 | 编译期警告 |
| 参数类型校验 | 无 | 推荐显式接口 |
| 页面管理 | 按 name 匹配 | 按 name + 类型匹配 |
2.2 严格模式下的 Builder 写法
@Builder
pageBuilder(name: string, param: Object) {
if (name === 'pages/Index') {
IndexPage({ param: param as IndexParam })
} else if (name === 'pages/Leaderboard') {
LeaderboardPage({ param: param as LeaderboardParam })
}
// 如果 name 没有匹配任何条件 → 严格模式下编译报错
}
2.3 定义参数接口
// 为每个页面定义参数类型
interface IndexParam {
fromLogin?: boolean;
}
interface LeaderboardParam {
highScore: number;
playerName?: string;
}
interface SettingsParam {
tab?: number;
}
三、多模块页面注册
3.1 拆分为多个 Builder
当页面数量增多时,拆分为多个 Builder 文件:
// pageBuilder.ets — 统一路由表
@Builder
export function PageBuilder(name: string, param: Object) {
if (name.startsWith('pages/game/')) {
GamePageBuilder(name, param)
} else if (name.startsWith('pages/user/')) {
UserPageBuilder(name, param)
} else if (name.startsWith('pages/shop/')) {
ShopPageBuilder(name, param)
}
}
// gamePages.ets
@Builder
function GamePageBuilder(name: string, param: Object) {
if (name === 'pages/game/Board') {
GameBoard({ param })
} else if (name === 'pages/game/Over') {
GameOver({ param })
}
}
3.2 跨 HAP 模块注册
// feature 模块暴露的路由注册函数
export function registerRankingRoutes(stack: NavPathStack) {
stack.pushPath({
name: 'pages/ranking/Main',
param: {}
})
}
// entry 模块使用
import { registerRankingRoutes } from '@ohos/rankingFeature';
registerRankingRoutes(this.navStack);
四、 navDestination 与 NavigationMode
4.1 NavigationMode 导航模式
this.navStack.pushPath({
name: 'pages/Leaderboard',
mode: NavigationMode.STANDARD // 标准模式(默认)
// mode: NavigationMode.REPLACE // 替换模式
})
| 模式 | 说明 |
|---|---|
STANDARD |
标准压栈(默认) |
REPLACE |
替换当前栈顶页 |
五、总结
navDestination @Builder 是 Navigation 的"路由表",通过集中注册页面名称到组件映射关系,实现 type-safe 的页面跳转。
核心要点:
.navDestination(this.pageBuilder)注册所有目标页@Builder中通过 name 匹配返回对应NavDestination组件- 严格模式(
enableStrictMode(true))提供编译期检查 - 多模块场景下可以拆分多个 Builder
- NavigationMode 控制压栈/替换模式
下一篇预告:第 86 篇将深入 NavPathStack 的查询 API——getAllPathName、getParamByName 等栈操作。
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源:
所有评论(0)