HarmonyOs应用《日记本》开发第19篇 - 页面路由与导航机制
·
本篇深入探讨鸿蒙 ArkUI 中的页面路由系统,分析日记应用中三个页面之间的导航关系和参数传递机制。

一、路由概述
在鸿蒙 ArkUI 中,页面路由通过 @ohos.router 模块实现。日记应用包含三个页面,它们之间形成了清晰的导航关系:
┌──────────────┐
│ Index │
│ (日记列表) │
└──────┬───────┘
│
pushUrl ┌────┴────┐ pushUrl
▼ ▼
┌────────────┐ ┌──────────────┐
│ DiaryEdit │ │ DiaryDetail │
│ (编辑/新建) │ │ (详情查看) │
└──────┬─────┘ └──────┬───────┘
│ │
│ pushUrl │
└───────────────┘
二、路由配置
2.1 页面注册
在 main_pages.json 中注册所有页面:
{
"src": [
"pages/Index",
"pages/DiaryEdit",
"pages/DiaryDetail"
]
}
配置说明:
src数组列出所有页面路径- 第一个页面
pages/Index是应用的入口页面 - 路径相对于
src/main/ets/目录
2.2 页面文件位置
entry/src/main/ets/
├── pages/
│ ├── Index.ets # 日记列表页
│ ├── DiaryEdit.ets # 日记编辑页
│ └── DiaryDetail.ets # 日记详情页
三、路由跳转方式
3.1 pushUrl — 压栈跳转
import router from '@ohos.router'
// 跳转到编辑页(新建模式)
router.pushUrl({
url: 'pages/DiaryEdit',
params: { mode: 'create' }
})
// 跳转到详情页
router.pushUrl({
url: 'pages/DiaryDetail',
params: { id: diary.id }
})
pushUrl 特点:
- 将目标页面压入路由栈,当前页面保留在栈底
- 目标页面可以通过
router.back()返回当前页面 - 适合层级导航(列表 → 详情 → 编辑)
3.2 replaceUrl — 替换跳转
router.replaceUrl({
url: 'pages/Index',
params: {}
})
replaceUrl 特点:
- 用目标页面替换当前页面,当前页面出栈
- 无法通过
router.back()返回当前页面 - 适合登录后跳转主页等场景
3.3 back — 返回上一页
// 返回上一页
router.back()
// 返回指定页面
router.back({ url: 'pages/Index' })
3.4 clear — 清空路由栈
router.clear()
清空所有页面,通常在退出应用或切换用户时使用。
四、参数传递
4.1 发送参数
// 发送简单参数
router.pushUrl({
url: 'pages/DiaryDetail',
params: { id: 'abc123' }
})
// 发送复杂对象
router.pushUrl({
url: 'pages/DiaryEdit',
params: {
mode: 'edit',
id: 'abc123',
title: '日记标题',
content: '日记内容'
}
})
4.2 接收参数
aboutToAppear() {
const params = router.getParams() as Record<string, string>
if (params) {
const mode = params.mode // 'edit' 或 'create'
const id = params.id // 日记ID
const title = params.title // 日记标题
}
}
参数接收注意事项:
router.getParams()返回Object类型,需要类型断言- 在
aboutToAppear生命周期中获取参数 - 需要进行空值检查,防止参数缺失导致崩溃
4.3 参数传递的完整示例
Index 页面跳转到 Detail:
// Index.ets
private goToDetail(diaryId: string) {
router.pushUrl({
url: 'pages/DiaryDetail',
params: { id: diaryId }
})
}
Detail 页面接收参数:
// DiaryDetail.ets
aboutToAppear() {
const params = router.getParams() as Record<string, string>
if (params && params.id) {
this.diaryId = params.id
this.loadDiaryDetail(params.id)
}
}
Detail 页面跳转到 Edit:
// DiaryDetail.ets
private goToEdit() {
router.pushUrl({
url: 'pages/DiaryEdit',
params: { mode: 'edit', id: this.diaryId }
})
}
Edit 页面接收参数:
// DiaryEdit.ets
aboutToAppear() {
const params = router.getParams() as Record<string, string>
if (params && params.mode === 'edit') {
this.isEditMode = true
this.editId = params.id
this.loadDiary(params.id)
}
}
五、路由动画
5.1 默认动画
鸿蒙默认提供页面切换动画:
- push:从右向左滑入
- back:从左向右滑出
5.2 自定义动画
router.pushUrl({
url: 'pages/DiaryDetail',
params: { id: diaryId },
animations: {
duration: 300,
curve: Curve.EaseInOut,
direction: AnimationDirection.RightToLeft
}
})
六、路由模式
6.1 Standard(默认)
router.pushUrl({
url: 'pages/DiaryDetail',
params: { id: diaryId }
}, router.RouterMode.Standard)
每次跳转都创建新页面实例,路由栈可能出现多个相同页面。
6.2 Single
router.pushUrl({
url: 'pages/DiaryDetail',
params: { id: diaryId }
}, router.RouterMode.Single)
如果路由栈中已有该页面,将其上方的页面全部出栈,复用该页面。
七、路由栈管理
7.1 路由栈结构
初始状态:
┌──────────┐
│ Index │ ← 栈底
└──────────┘
跳转到 Detail:
┌──────────┐
│ Detail │ ← 栈顶
├──────────┤
│ Index │ ← 栈底
└──────────┘
跳转到 Edit:
┌──────────┐
│ Edit │ ← 栈顶
├──────────┤
│ Detail │
├──────────┤
│ Index │ ← 栈底
└──────────┘
back 返回 Detail:
┌──────────┐
│ Detail │ ← 栈顶
├──────────┤
│ Index │ ← 栈底
└──────────┘
7.2 获取路由栈信息
const stackSize = router.getLength()
const stack = router.getState()
console.log(`当前路由栈大小: ${stackSize}`)
console.log(`当前页面: ${stack.name}`)
八、路由返回携带参数
8.1 通过全局状态
// 编辑页面保存成功后设置全局状态
AppStorage.Set('diaryUpdated', true)
router.back()
// 列表页面检查
onPageShow() {
const updated = AppStorage.Get<boolean>('diaryUpdated')
if (updated) {
this.loadDiaries()
AppStorage.Set('diaryUpdated', false)
}
}
8.2 通过 router.back params
// 编辑页面
router.back({ url: 'pages/Index' })
// 列表页面在 onPageShow 中刷新
onPageShow() {
this.loadDiaries()
}
九、路由守卫与拦截
虽然鸿蒙没有直接的路由守卫 API,但可以通过封装路由方法实现拦截:
export class RouterUtil {
static pushUrl(url: string, params?: Record<string, string>) {
// 前置检查
if (!this.checkPermission(url)) {
promptAction.showToast({ message: '无访问权限' })
return
}
router.pushUrl({ url, params })
}
static checkPermission(url: string): boolean {
// 权限检查逻辑
return true
}
}
十、总结
鸿蒙路由系统的核心要点:
- 页面注册:在
main_pages.json中声明所有页面 - 跳转方式:
pushUrl(压栈)、replaceUrl(替换)、back(返回) - 参数传递:通过
params传递,通过router.getParams()接收 - 路由模式:
Standard(多实例)和Single(单例) - 栈管理:理解路由栈结构,合理使用
back和clear - 页面刷新:通过
onPageShow生命周期实现返回后刷新
日记应用的路由设计简洁清晰,列表 → 详情 → 编辑的三层导航是移动应用的经典模式。
更多推荐




所有评论(0)