主题
ArkTS 页面加载与导航机制
一、页面加载链路(启动 App → 显示首页)
启动 App
│
▼
EntryAbility.ets
│ windowStage.loadContent('pages/Index')
▼
main_pages.json → 查找 "pages/Index"
│
▼
pages/Index.ets → 渲染 @Entry @Component| 步骤 | 文件 | 作用 |
|---|---|---|
| ① 声明 | module.json5 → "pages": "$profile:main_pages" | 引用页面配置文件 |
| ② 注册 | main_pages.json → { "src": ["pages/Index"] } | 列出所有页面路径 |
| ③ 加载 | EntryAbility.ets → loadContent('pages/Index') | 启动首页 |
pages/Index=pages/Index.ets(省略.ets)- 子页面(NavDestination)不需要注册到
main_pages.json,只有入口页面需要
二、Navigation 页面导航(官方推荐,替代废弃的 router.pushUrl)
核心架构
Index.ets @Entry
├── @Provide('NavPathStack') pageStack ← 路由栈(响应式)
├── Navigation(this.pageStack) ← 容器组件
│ └── navDestination(this.PagesMap) ← name → 组件映射
│
├── HomePage.ets(@Component,子页面)
│ └── NavDestination() {...} ← 子页面根节点
│ @Consume('NavPathStack') pageStack
│
└── TodoPage.ets(@Component,子页面)
└── NavDestination() {...}
@Consume('NavPathStack') pageStackNavPathStack 原理(类数组结构)
内部维护数组:this.stack = [
{ name: 'Home', param: null },
{ name: 'Todo', param: { from: 'home' } }, ← 栈顶
]| 方法 | 作用 | 类比 |
|---|---|---|
pushPathByName(name, param) | 入栈 | history.pushState() |
pop() | 出栈返回上一页 | history.back() |
clear() | 清空栈 | — |
pushPath(info) | 入栈(对象形式) | — |
完整导航流程
pushPathByName('Todo', param)
│ ① 往数组 push({name, param})
▼
@Provide 检测到变化
│ ② 通知 Navigation 栈变了
▼
Navigation 重新渲染
│ ③ 查栈顶 name = 'Todo'
▼
navDestination → PagesMap 匹配
│ ④ if (name === 'Todo') → TodoPage()
▼
NavDestination 组件挂载渲染三、@Provide / @Consume 装饰器
作用
@Provide('key'):父组件把变量广播给所有后代组件@Consume('key'):子组件接收同一个变量(直接读写,无需逐层传参)
类比
| ArkTS | Vue | React |
|---|---|---|
@Provide / @Consume | provide / inject | Context.Provider / useContext() |
特点
- 跨层级共享(不管子组件嵌多深)
- 响应式(变量变了,所有引用的组件自动刷新)
'NavPathStack'是 key,父子必须用同一个字符串匹配
四、关键区别:旧路由 vs 新导航
| 对比项 | router.pushUrl(废弃) | Navigation(推荐) |
|---|---|---|
| 自版本 | API 9 | API 12+ |
| 子页面需要 | @Entry + 注册 main_pages.json | @Component + NavDestination |
| 路由表 | main_pages.json | navDestination @Builder |
| 页面栈控制 | 基础(push/back/clear) | 丰富(popTo/removeByName/moveToTop 等) |
| 转场动画 | 有限 | 支持自定义 + 共享元素动画 |
| 路由拦截 | 不支持 | 支持 setInterception |