
阅读时长:约 18 分钟 | 难度:★★★★☆ | 篇章:第 1 篇 · 项目架构与设计哲学
对应源码:
entry/src/main/ets/pages/Index.ets、resources/base/profile/main_pages.json

前言
在 HarmonyOS ArkUI 开发中,路由根 是整个应用页面体系的入口。玄象项目通过 Index.ets + Navigation 容器搭建路由根,承载启动页 SplashPage 与后续所有页面的跳转逻辑。本篇将深入剖析玄象项目的路由根搭建方式,从 @Entry 注解、Navigation 容器、路由表注册,到 router.pushUrl / router.replaceUrl 的差异,全面掌握 HarmonyOS 应用页面跳转的核心机制。
提示:路由体系是应用骨架。良好的路由设计能让后续模块开发事半功倍,反之则会埋下诸多维护陷阱。
一、Index.ets 路由根全貌
1.1 完整源码
typescript
import { Colors } from '../common/constants/Colors';
import { SplashPage } from './SplashPage';
@Entry
@Component
struct Index {
build() {
Navigation() {
// 启动页作为初始页面
SplashPage()
}
.hideTitleBar(true)
.width('100%')
.height('100%')
.backgroundColor(Colors.BG_DARK)
}
}
1.2 关键要素解析
玄象项目的 Index.ets 仅 17 行,却承载了应用路由的核心逻辑:
| 要素 | 含义 | 玄象用途 |
|---|---|---|
@Entry |
标记组件为页面入口 | Index 作为应用启动后第一个加载的页面 |
@Component |
标记 struct 为自定义组件 | 让 Index 可被 ArkUI 渲染 |
Navigation() |
路由导航容器 | 提供页面栈管理与转场动画 |
SplashPage() |
子组件引用 | 启动页作为初始内容 |
.hideTitleBar(true) |
隐藏默认标题栏 | 启动页不需要标题栏 |
提示:
@Entry与@Component必须同时使用。仅用@Component而无@Entry的组件是普通子组件,不能独立加载。
二、@Entry 注解深入解析
2.1 @Entry 的作用
@Entry 注解将一个 @Component 标记为页面入口组件。HarmonyOS 应用启动后,会加载 main_pages.json 中注册的第一个 @Entry 页面。
2.2 @Entry 的使用规范
玄象项目 Index.ets 的 @Entry 使用规范:
- 唯一性 :每个
@Entry必须对应main_pages.json中注册的一个页面路径。 - 必须配合 @Component :
@Entry修饰的 struct 必须同时被@Component修饰。 - build 方法唯一 :
@Entry组件的build方法返回单个根容器(Navigation、Column等)。
2.3 @Entry 与普通组件的区别
typescript
// @Entry 页面(路由可直达)
@Entry
@Component
struct SplashPage {
build() {
// ...
}
}
// 普通子组件(需被其他组件引用)
@Component
export struct GoldButton {
build() {
// ...
}
}
三、Navigation 容器详解
3.1 Navigation 的核心作用
Navigation 是 ArkUI 提供的 路由导航容器,主要功能包括:
- 页面栈管理:自动维护页面入栈 / 出栈。
- 转场动画:提供默认的 push / pop 转场动画。
- 标题栏管理 :可通过
hideTitleBar(true)隐藏。 - 工具栏管理:支持自定义底部工具栏。
3.2 Navigation 的常见用法
typescript
@Entry
@Component
struct Index {
@Provide('navPathStack') navPathStack: NavPathStack = new NavPathStack();
build() {
Navigation(this.navPathStack) {
// 初始内容
HomePage()
}
.hideTitleBar(true)
.navDestination(this.PageMap)
}
@Builder
PageMap(name: string) {
if (name === 'detail') {
DetailPage()
} else if (name === 'list') {
ListPage()
}
}
}
提示:玄象项目当前使用
Navigation()的最简形式,仅承载启动页。本系列后续篇章会演示NavPathStack与navDestination的进阶用法。
3.3 Navigation 与 router 的协作
玄象项目同时使用 Navigation 容器与 router API:
Navigation:作为页面容器,提供统一的导航上下文。router.pushUrl:在 Navigation 内部 push 子页面。router.replaceUrl:替换当前页面(无返回)。
四、main_pages.json 路由表
4.1 路由表的作用
main_pages.json 是 HarmonyOS 应用的 路由表 ,声明所有可被 router API 加载的页面路径。未在路由表注册的页面无法跳转。
4.2 玄象项目路由表结构
玄象项目路由表位于 entry/src/main/resources/base/profile/main_pages.json,结构如下:
json5
{
"src": [
"pages/Index",
"pages/SplashPage",
"pages/HomePage",
"pages/mansion/MansionListPage",
"pages/mansion/MansionDetailPage",
"pages/mansion/StarTerritoryPage",
"pages/yijing/YijingHomePage",
"pages/yijing/HexagramsPage",
"pages/yijing/GreatWheelPage",
"pages/yijing/CastDivinationPage",
"pages/mingli/BaziInputPage",
"pages/mingli/MingliAnalysisPage",
"pages/mingli/FortuneTimelinePage",
"pages/fengshui/FengshuiHomePage",
"pages/fengshui/LuopanPage",
"pages/fengshui/GpsFengshuiPage",
"pages/fengshui/AiPhotoFengshuiPage",
"pages/fengshui/FengshuiReportPage",
"pages/astronomy/LunarCalendarPage",
"pages/astronomy/MoonPhasesPage",
"pages/astronomy/SolarTermsPage",
"pages/astronomy/TwelveCiPage",
"pages/music/MusicTwelveLawsPage",
"pages/geography/NineProvincesPage",
"pages/naming/AiNamingPage",
"pages/naming/NamingResultPage",
"pages/assistant/AiAssistantPage",
"pages/profile/ProfilePage",
"pages/profile/MembershipPage",
"pages/stems/HeavenlyStemsPage",
"pages/stems/SixtyJiaziPage"
]
}
4.3 路由表注册规范
玄象项目的路由表注册遵循以下规范:
- 路径以
pages/开头 :与ets/pages/目录结构对应。 - 省略
.ets后缀:路由表声明组件名而非文件名。 Index必须注册 :作为应用主入口,pages/Index必须出现在路由表。@Entry组件必须注册 :每个@Entry修饰的页面都需要注册。
提示:路由表缺失会导致
router.pushUrl跳转失败。玄象项目在 DevEco Studio 中通过"配置路由"功能自动维护路由表。
五、router.pushUrl 与 router.replaceUrl
5.1 pushUrl:入栈跳转
router.pushUrl 将目标页面压入页面栈,用户可通过返回键回到前一页面。
typescript
import { router } from '@kit.ArkUI';
// 跳转到星宿列表页
router.pushUrl({ url: 'pages/mansion/MansionListPage' });
5.2 replaceUrl:替换跳转
router.replaceUrl 用目标页面替换当前页面,无返回栈记录。
typescript
import { router } from '@kit.ArkUI';
// 启动页 3 秒后替换为首页
router.replaceUrl({ url: 'pages/HomePage' });
5.3 pushUrl 与 replaceUrl 对比
| 维度 | router.pushUrl |
router.replaceUrl |
|---|---|---|
| 栈操作 | 入栈 | 替换栈顶 |
| 返回键 | 可返回上一页 | 无前一页可返回 |
| 典型场景 | 功能页跳转 | 启动页 → 首页 |
| 内存占用 | 累积增加 | 等量替换 |
提示:玄象项目启动页
SplashPage用replaceUrl跳转到首页,避免用户按返回键回到启动页。
5.4 携带参数的跳转
玄象项目支持携带参数的跳转,通过 params 字段传递:
typescript
// 携带星宿 ID 跳转到详情页
router.pushUrl({
url: 'pages/mansion/MansionDetailPage',
params: {
mansionId: 'jiao',
mansionName: '角宿'
}
});
// 在目标页面接收参数
@Entry
@Component
struct MansionDetailPage {
@State mansionId: string = router.getParams()['mansionId'];
@State mansionName: string = router.getParams()['mansionName'];
}
六、玄象项目路由流转全貌
6.1 启动流转
text
应用启动
↓
EntryAbility.onWindowStageCreate()
↓
windowStage.loadContent('pages/Index')
↓
Index.build() → Navigation() { SplashPage() }
↓
SplashPage aboutToAppear()
↓
setTimeout 3 秒
↓
router.replaceUrl({ url: 'pages/HomePage' })
↓
HomePage.build() 渲染首页
6.2 功能页跳转流转
text
HomePage FeatureGrid 九宫格
↓
onClick → router.pushUrl({ url: 'pages/mansion/MansionListPage' })
↓
MansionListPage.build() 渲染星宿列表
↓
ListItem onClick → router.pushUrl({
url: 'pages/mansion/MansionDetailPage',
params: { mansionId: 'jiao' }
})
↓
MansionDetailPage.build() 渲染星宿详情
提示:玄象项目所有功能页均通过
router.pushUrl跳转,返回时通过router.back()或系统返回键自动出栈。
七、Navigation 容器的进阶用法
7.1 NavPathStack 动态路由
玄象项目未来可引入 NavPathStack 实现更灵活的动态路由:
typescript
@Entry
@Component
struct Index {
private navStack: NavPathStack = new NavPathStack();
build() {
Navigation(this.navStack) {
SplashPage()
}
.hideTitleBar(true)
}
}
// 在任意子组件中
this.navStack.pushPath({ name: 'mansionDetail', param: { id: 'jiao' } });
7.2 自定义转场动画
typescript
Navigation(this.navStack) {
// ...
}
.customNavContentTransition((from: NavContentInfo, to: NavContentInfo, op: NavigationOperation) => {
// 自定义转场动画
return {
timeout: 300,
transition: (transitionProxy) => {
// 动画实现
}
};
})
7.3 Tab 容器组合
玄象项目底部导航栏未来可使用 Tabs 容器替代 @State currentTab 方案:
typescript
Tabs() {
TabContent() {
HomePage()
}.tabBar('首页')
TabContent() {
ExplorePage()
}.tabBar('探索')
TabContent() {
ProfilePage()
}.tabBar('我的')
}
八、路由设计的最佳实践
8.1 路由命名规范
玄象项目的路由命名遵循 功能模块/页面名 模式:
text
pages/mansion/MansionListPage
pages/yijing/YijingHomePage
pages/fengshui/LuopanPage
- 目录前缀:与功能模块对应。
- 页面名后缀 :统一以
Page结尾。 - 驼峰命名 :
MansionListPage而非mansion_list_page。
8.2 路由跳转的封装
玄象项目在 HomePage 中直接调用 router.pushUrl,规模扩大后建议封装路由工具:
typescript
// common/utils/RouterUtil.ets
import { router } from '@kit.ArkUI';
export class RouterUtil {
static push(url: string, params?: Record<string, object>): void {
router.pushUrl({ url, params });
}
static replace(url: string, params?: Record<string, object>): void {
router.replaceUrl({ url, params });
}
static back(): void {
router.back();
}
static getParams<T>(): T {
return router.getParams() as T;
}
}
// 使用
RouterUtil.push('pages/mansion/MansionListPage');
8.3 路由守卫
玄象项目未来可引入路由守卫,实现登录校验、权限校验等:
typescript
static push(url: string, params?: Record<string, object>): void {
if (this.requiresAuth(url) && !this.isLoggedIn()) {
router.pushUrl({ url: 'pages/profile/LoginPage' });
return;
}
router.pushUrl({ url, params });
}
总结
本篇以玄象项目 Index.ets 为蓝本,深入剖析了 HarmonyOS 应用的路由根搭建:从 @Entry 注解、Navigation 容器、main_pages.json 路由表,到 router.pushUrl / router.replaceUrl 的差异与参数传递。掌握这套路由体系,是后续所有 ArkUI 页面实战的基础。
下一篇:《06 · 多 Ability 还是单 Ability?EntryAbility 与 EntryBackupAbility 的取舍》,将带您进入玄象项目的 Ability 设计决策环节。
如果这篇文章对你有帮助,欢迎点赞👍、收藏⭐、关注🔔,你的支持是我持续创作的动力!
相关资源:
- HarmonyOS 官方文档:Navigation 组件
- HarmonyOS 官方文档:router API
- HarmonyOS 官方文档:页面路由
- 开源鸿蒙跨平台社区:https://openharmonycrossplatform.csdn.net