鸿蒙学习-组件导航(Navigation)
一、导航系统架构
1. 核心组件关系
A[Navigation] --> B[NavDestination] A --> C[NavRouter] B --> D[页面组件] C --> E[路由逻辑] A --> F[NavPathStack]
2. 分层实现
| 层级 | 组件 | 职责 |
|---|---|---|
| 路由容器 | Navigation |
管理导航堆栈和页面容器 |
| 页面节点 | NavDestination |
承载具体页面内容 |
| 路由控制 | NavRouter |
处理路由跳转逻辑 |
| 堆栈管理 | NavPathStack |
维护页面历史记录 |
二、基础导航开发
1. 静态路由注册
// 在导航容器中注册页面 @Entry @Component struct AppRoot { build() { Navigation() { // 注册首页 NavDestination() { HomePage() }.title('首页').id('home') // 注册详情页 NavDestination() { DetailPage() }.title('详情').id('detail') } } }
2. 动态路由跳转
// 通过路由ID跳转 import { router } from '@ohos.router'; function navigateToDetail() { router.pushUrl({ url: 'pages/DetailPage', // 目标页面路径 params: { id: 123 } // 传递参数 }, router.RouterMode.Standard); } // 返回上一页 router.back();
三、高级路由功能
1. 参数传递与接收
发送参数:
router.pushUrl({ url: 'pages/DetailPage', params: { itemId: '1001', source: 'home' } });
接收参数:
typescript
复制
下载
@State itemId: string = '';
@State source: string = '';
onPageShow() {
const params = router.getParams();
this.itemId = params?.['itemId'] ?? '';
this.source = params?.['source'] ?? '';
}
2. 路由拦截器
// 全局前置守卫 router.addBeforeInterceptor((to, from, next) => { if (to.url === 'pages/PayPage' && !isLogin()) { next({ url: 'pages/LoginPage' }); // 重定向到登录 } else { next(); // 放行 } }); // 全局后置守卫 router.addAfterInterceptor(() => { trackPageView(); // 页面访问统计 });
3. 深度链接(DeepLink)
配置manifest:
// module.json5 "abilities": [{ "name": "EntryAbility", "deepLinks": [{ "scheme": "myapp", "host": "product", "path": "/detail" }] }]
处理DeepLink:
// EntryAbility.ts onCreate(want) { if (want.uri?.startsWith('myapp://product/detail')) { const id = extractIdFromUri(want.uri); // 解析参数 router.pushUrl({ url: `pages/DetailPage`, params: { id } }); } }
四、导航栏定制化
1. 自定义导航栏
Navigation() { NavDestination() { // 页面内容 } }.titleMode(NavigationTitleMode.Free) // 自由模式 .navBar(this.CustomNavBar()) // 自定义导航栏组件
2. 自定义导航栏组件
@Component struct CustomNavBar { @State title: string = '默认标题'; build() { Row() { Image($r('app.media.back')) .onClick(() => router.back()) Text(this.title) .fontSize(20) Button('分享') }.padding(10) } }
3. 动态更新导航栏
// 在页面中更新导航栏 import { NavigationUtils } from '@ohos.arkui.navigation'; onPageShow() { NavigationUtils.setTitle({ title: '商品详情' }); NavigationUtils.setRightButton({ icon: $r('app.media.share'), action: () => this.shareProduct() }); }
五、导航模式
1. 标准模式(Stack)
router.pushUrl({ url: 'pages/PageA' }, router.RouterMode.Standard);
-
特点:页面入栈,保留历史记录
2. 单例模式(Singleton)
router.replaceUrl({ url: 'pages/LoginPage' }, router.RouterMode.Single);
-
特点:替换当前页面,无返回栈
3. 多实例模式(Multi)
router.pushUrl({ url: 'pages/ChatPage', params: { userId } }, router.RouterMode.Multi);
-
特点:允许同页面多个实例(如聊天窗口)
六、导航动画
1. 预设动画
router.pushUrl({ url: 'pages/DetailPage', transition: { type: router.TransitionType.Push, curve: router.TransitionCurve.EaseOut } });
2. 自定义动画
// 目标页面配置 @CustomDialogTransition({ slideIn: { slide: { from: SlideEdge.End, to: SlideEdge.Start }, curve: Curve.EaseOut, duration: 300 }, slideOut: { // 退出动画 } }) @Component struct SlidePage { ... }
七、最佳实践
1. 路由规范
| 路由类型 | 命名规则 | 示例 |
|---|---|---|
| 主功能页面 | /module/PageName |
/home/Index |
| 详情页 | /detail/:id |
/detail/1001 |
| 模态窗口 | /modal/ModalName |
/modal/FilterModal |
2. 性能优化
-
懒加载:
NavDestination() { LazyForEach(this.data, item => { ProductItem({ data: item }) }) }
-
页面缓存:
NavDestination() { DetailPage() }.cachedCount(3) // 缓存最近3个页面实例
3. 异常处理
router.pushUrl({ url: 'pages/PageX' }) .catch((err: BusinessError) => { if (err.code === 100001) { console.error('页面不存在'); } });
八、常见问题解决方案
| 问题场景 | 解决方案 |
|---|---|
| 页面返回空白 | 检查NavDestination组件嵌套是否正确 |
| 参数传递丢失 | 使用JSON.stringify转换复杂对象 |
| 多级返回混乱 | 使用router.clear()清空非必要历史堆栈 |
| 自定义导航栏闪动 | 在aboutToAppear中初始化导航栏状态 |
华为官方建议:
使用
router.getLength()监控路由栈深度(超过10层需优化)遵循一个容器对应一个导航原则避免嵌套冲突
生产环境开启路由日志:
router.enableLogger()
更多推荐

所有评论(0)