鸿蒙系统提供了两种主要的路由机制:传统的Router模块和组件化的Navigation容器。下面我将详细介绍这两种路由方式的使用方法、区别以及实际应用示例。
一、Router模块基础使用
Router是鸿蒙早期提供的页面路由模块,通过URL实现页面跳转和数据传递。
1. 基本跳转方法
Router提供了两种跳转模式:
TypeScript
import router from '@ohos.router';
// 1. pushUrl - 保留当前页,新页面压入栈
router.pushUrl({
url: 'pages/DetailPage'
});
// 2. replaceUrl - 替换当前页,销毁当前页
router.replaceUrl({
url: 'pages/LoginPage'
});
2. 实例模式
Router支持两种页面实例模式:
TypeScript
// Standard模式(默认) - 每次跳转都新建实例
router.pushUrl({
url: 'pages/DetailPage'
}, router.RouterMode.Standard);
// Single模式 - 单实例,已存在则复用
router.pushUrl({
url: 'pages/SettingPage'
}, router.RouterMode.Single);
3. 参数传递与接收
传递参数:
TypeScript
// 简单参数
router.pushUrl({
url: 'pages/DetailPage',
params: { id: 123, name: '商品1' }
});
// 复杂对象
interface Product {
id: number;
name: string;
}
const product: Product = { id: 1, name: '手机' };
router.pushUrl({
url: 'pages/DetailPage',
params: { product: JSON.stringify(product) }
});
接收参数:
TypeScript
// 在目标页面
onPageShow() {
const params = router.getParams();
const id = params['id'];
const product: Product = JSON.parse(params['product']);
}
二、Navigation组件详解
Navigation是鸿蒙官方推荐的路由容器组件,相比Router功能更强大。
1. 基本结构
TypeScript
@Entry
@Component
struct Index {
pageStack: NavPathStack = new NavPathStack()
build() {
Navigation(this.pageStack) {
// 首页内容
Button("点击跳转")
.onClick(() => {
this.pageStack.pushPath({ name: "DetailPage" })
})
}
.title("首页") // 设置标题
}
}
2. 目标页面配置
目标页面需要使用NavDestination作为根布局:
TypeScript
@Component
struct DetailPage {
build() {
NavDestination() {
// 页面内容
Text("详情页")
}
}
}
// 必须导出Builder函数
@Builder
export function DetailPageBuilder() {
DetailPage()
}
3. 路由表配置
在module.json5中添加配置:
TypeScript
{
"module": {
"routerMap": "$profile:route_map"
}
}
route_map.json内容:
TypeScript
{
"routerMap": [
{
"name": "DetailPage",
"pageSourceFile": "src/main/ets/pages/DetailPage.ets",
"buildFunction": "DetailPageBuilder"
}
]
}
三、高级路由功能
1. 路由守卫
可以实现全局拦截进行权限控制:
TypeScript
// 全局前置守卫
router.addBeforeHook((to, from, next) => {
if (to.url === 'pages/ProfilePage' && !isLogin) {
next({ url: 'pages/LoginPage' }) // 重定向
} else {
next() // 放行
}
});
2. 动态路由
实现按需加载模块:
TypeScript
// 动态导入模块并跳转
await import(moduleName).then((result: ESObject) => {
result.harInit(pageName);
DynamicsRouter.getNavPathStack().pushPath({ name: builderName });
});
3. 自定义转场动画
Router的动画功能较基础,若需高级效果(如共享元素转场),建议使用Navigation组件:
TypeScript
import router from '@ohos.router';
// 跳转时设置动画
router.pushUrl({
url: 'pages/DetailPage',
//入场动画效果
enterAnimation: {
duration: 500,
curve: Curve.EaseOut,
type: RouteAnimation.SlideRight // 目标页从右侧滑入
},
//退场动画
exitAnimation: {
duration: 300,
curve: Curve.Linear,
type: RouteAnimation.SlideLeft // 当前页向左滑出
}
});
//支持的动画类型:
//RouteAnimation.Slide:滑动效果(默认)。
//RouteAnimation.Translate:平移效果。
//RouteAnimation.Fade:淡入淡出效果。
//RouteAnimation.None:无动画。
四、Router与Navigation对比
特性 | Router | Navigation |
---|---|---|
类型 | API调用 | 组件容器 |
官方推荐 | 不再推荐 | 推荐使用 |
生命周期 | 标准页面生命周期 | NavDestination特有生命周期 |
复杂UI支持 | 有限 | 支持标题栏、工具栏等 |
跨模块跳转 | 支持 | 更优支持 |
学习曲线 | 简单 | 较复杂 |
适用场景 | 简单跳转 | 复杂应用路由 |
总结
鸿蒙路由系统提供了灵活强大的页面导航能力。对于新项目,建议使用Navigation组件作为路由框架,它提供了更完整的生命周期管理、UI集成和模块解耦能力。对于简单应用或维护旧代码,Router模块仍可使用,但功能相对有限。根据实际需求选择合适的路由方案,可以大大提高开发效率和用户体验。