本篇深入探讨鸿蒙 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 — 压栈跳转
importrouterfrom'@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(){constparams=router.getParams()asRecord<string,string>if(params){constmode=params.mode// 'edit' 或 'create'constid=params.id// 日记IDconsttitle=params.title// 日记标题}}参数接收注意事项:
router.getParams()返回Object类型,需要类型断言- 在
aboutToAppear生命周期中获取参数 - 需要进行空值检查,防止参数缺失导致崩溃
4.3 参数传递的完整示例
Index 页面跳转到 Detail:
// Index.etsprivategoToDetail(diaryId:string){router.pushUrl({url:'pages/DiaryDetail',params:{id:diaryId}})}Detail 页面接收参数:
// DiaryDetail.etsaboutToAppear(){constparams=router.getParams()asRecord<string,string>if(params&¶ms.id){this.diaryId=params.idthis.loadDiaryDetail(params.id)}}Detail 页面跳转到 Edit:
// DiaryDetail.etsprivategoToEdit(){router.pushUrl({url:'pages/DiaryEdit',params:{mode:'edit',id:this.diaryId}})}Edit 页面接收参数:
// DiaryEdit.etsaboutToAppear(){constparams=router.getParams()asRecord<string,string>if(params&¶ms.mode==='edit'){this.isEditMode=truethis.editId=params.idthis.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 获取路由栈信息
conststackSize=router.getLength()conststack=router.getState()console.log(`当前路由栈大小:${stackSize}`)console.log(`当前页面:${stack.name}`)八、路由返回携带参数
8.1 通过全局状态
// 编辑页面保存成功后设置全局状态AppStorage.Set('diaryUpdated',true)router.back()// 列表页面检查onPageShow(){constupdated=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,但可以通过封装路由方法实现拦截:
exportclassRouterUtil{staticpushUrl(url:string,params?:Record<string,string>){// 前置检查if(!this.checkPermission(url)){promptAction.showToast({message:'无访问权限'})return}router.pushUrl({url,params})}staticcheckPermission(url:string):boolean{// 权限检查逻辑returntrue}}十、总结
鸿蒙路由系统的核心要点:
- 页面注册:在
main_pages.json中声明所有页面 - 跳转方式:
pushUrl(压栈)、replaceUrl(替换)、back(返回) - 参数传递:通过
params传递,通过router.getParams()接收 - 路由模式:
Standard(多实例)和Single(单例) - 栈管理:理解路由栈结构,合理使用
back和clear - 页面刷新:通过
onPageShow生命周期实现返回后刷新
日记应用的路由设计简洁清晰,列表 → 详情 → 编辑的三层导航是移动应用的经典模式。