本文同步发表于我的微信公众号,微信搜索 程语新视界 即可关注,每个工作日都有文章更新
一、Router 核心概念
1. 功能定位
- 作用:实现页面跳转、参数传递和页面栈管理,适用于模块间解耦的页面导航 。
- 与Navigation对比:
- Router:轻量级跳转,适合跨模块解耦(如商品页跳订单页) 。
- Navigation:堆栈式管理,适合线性流程(如注册流程) 。
2. 页面栈规则
- 最大容量:32个页面,超出需调用
router.clear()
清理 。 - 实例模式:
Standard
:每次跳转新建实例(默认) 。Single
:复用已有页面(如设置页避免重复创建) 。
3. Single模式的核心规则(底层原理:移动而非复用)
- 当跳转到
Single
页面时:- 若目标页已存在栈中,会将该页面移动到栈顶(非复用原位置实例)
- 原页面上方的其他页面顺序不变(仅目标页位置变化)
// 初始栈:[A, B, C(Single), D]
router.pushUrl({
url: 'pages/C',
params: { id: 123 }
}, router.RouterMode.Single);
// 跳转后实际栈状态:[A, B, D, C]
与常见误解的对比
错误理解 | 实际行为 | 图示说明 |
---|---|---|
认为会清空C上方的D | D保留且顺序不变 | [A, B, D] → [A, B, D, C] |
认为C在原位复用 | C被移动到栈顶 | [A, B, C, D] → [A, B, D, C] |
二、核心API与使用示例
1. 基础跳转方法
API | 说明 | 示例代码 |
---|---|---|
pushUrl | 跳转并压栈(保留当前页) | router.pushUrl({ url: 'pages/DetailPage', params: { id: 123 } }) |
replaceUrl | 替换当前页(销毁当前页) | router.replaceUrl({ url: 'pages/Login' }) |
back | 返回上一页 | router.back({ result: { status: 'SUCCESS' } }) |
getParams | 获取跳转参数 | const params = router.getParams(); |
2. 参数传递与接收
// 跳转传参(支持复杂对象)
class DataModel {
id: number;
name: string;
}
router.pushUrl({
url: 'pages/DetailPage',
params: new DataModel(1, 'HarmonyOS')
});
// 目标页接收参数
@Component
struct DetailPage {
@State id: number = 0;
aboutToAppear() {
const params = router.getParams();
this.id = params?.id || 0;
}
}
注意:参数不能传递函数或系统对象
3. 页面栈管理
API | 说明 | 示例 |
---|---|---|
getLength | 获取页面栈深度 | const depth = router.getLength(); |
getState | 获取当前页面状态 | const state = router.getState(); // { index, name, path } |
clear | 清空页面栈(慎用) | router.clear(); |
三、高级功能与场景
1. 路由拦截器
// 登录拦截示例
router.addInterceptor((to, from) => {
if (to.url === 'pages/PayPage' && !isLogin) {
return { url: 'pages/Login' }; // 重定向
}
return to; // 放行
});
2. 动态导入与懒加载
// 按需加载页面模块
RouterManager.openWithRequest({
url: 'dynamicHar/DetailPage',
params: { id: 123 }
});
3. 混合路由模式
// Standard与Single模式混合使用
router.pushUrl({
url: 'pages/ThemeSettings',
params: { theme: 'dark' }
}, router.RouterMode.Single); // 确保主题页唯一
四、优化与调试
1. 性能优化
- Single模式:高频跳转页面(如商品详情)使用单例 。
- 参数精简:传递ID而非大对象,目标页重新查询 。
- 清理时机:页面栈深度超过20时提示清理 。
2. 常见问题
问题 | 解决方案 |
---|---|
URI不存在错误 | 检查main_pages.json 是否配置路径 |
参数丢失 | 使用aboutToAppear 生命周期而非onInit 接收参数 |
页面重复创建 | 切换为Single 模式或复用已有实例 |
3. 调试技巧
// 打印页面栈信息
console.log(JSON.stringify(router.getState(), null, 2));
五、完整购物车跳转示例
// 商品页跳转逻辑
@Entry
@Component
struct ProductPage {
build() {
Button('加入购物车')
.onClick(() => {
router.pushUrl({
url: 'pages/CartPage',
params: { productId: 123 },
routerMode: router.RouterMode.Single // 购物车页唯一
});
});
}
}
// 购物车页接收参数
@Component
struct CartPage {
@State productId: number = 0;
aboutToAppear() {
this.productId = router.getParams()?.productId || 0;
}
}
六、与Navigation的选型建议
场景 | 推荐方案 | 理由 |
---|---|---|
跨模块跳转(如App内H5) | Router | 解耦性强,无需共享UI上下文 |
线性流程(如注册步骤) | Navigation | 状态自动保存,内置动画 |
高频跳转(如Tab页) | Navigation + Tabs | 避免Router的实例重复创建 |