news 2026/7/7 18:31:37

[鸿蒙2025领航者闯关]HarmonyOS路由跳转

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
[鸿蒙2025领航者闯关]HarmonyOS路由跳转

问题描述

应用需要页面跳转和参数传递:

  • 点击按钮跳转到详情页
  • 携带参数跳转
  • 返回时传递结果
  • 路由拦截和鉴权

关键字:Router页面跳转参数传递路由导航

解决方案

1. 基础路由跳转

import { router } from '@kit.ArkUI'; ​ @Entry @Component struct HomePage { build() { Column({ space: 16 }) { // ✅ 方式1: pushUrl跳转(可返回) Button('查看详情') .onClick(() => { router.pushUrl({ url: 'pages/DetailPage' }); }) // ✅ 方式2: replaceUrl跳转(不可返回) Button('登录') .onClick(() => { router.replaceUrl({ url: 'pages/LoginPage' }); }) // ✅ 方式3: back返回 Button('返回') .onClick(() => { router.back(); }) } } }

2. 携带参数跳转

// 发送页面 @Component struct ItemList { onItemClick(item: Item): void { // ✅ 通过params传递参数 router.pushUrl({ url: 'pages/ItemDetailPage', params: { itemId: item.id, itemName: item.name, // ✅ 可以传递对象 itemData: item } }, router.RouterMode.Standard); } build() { List() { ForEach(this.items, (item: Item) => { ListItem() { Text(item.name) } .onClick(() => { this.onItemClick(item); }) }) } } } ​ // 接收页面 @Entry @Component struct ItemDetailPage { @State itemId: number = 0; @State itemName: string = ''; @State itemData: Item | null = null; aboutToAppear(): void { // ✅ 获取路由参数 const params = router.getParams() as Record<string, Object>; this.itemId = params.itemId as number; this.itemName = params.itemName as string; this.itemData = params.itemData as Item; console.info('接收参数:', this.itemId, this.itemName); } build() { Column() { Text(`ID: ${this.itemId}`) Text(`名称: ${this.itemName}`) } } }

3. 返回并传递结果

// 页面A: 打开页面B @Component struct PageA { @State selectedValue: string = ''; async openSelector(): Promise<void> { // ✅ 打开选择器页面 await router.pushUrl({ url: 'pages/SelectorPage' }); // ✅ 监听返回结果 router.getParams(); // 获取返回的数据 } aboutToAppear(): void { // ✅ 页面重新显示时获取结果 const params = router.getParams() as Record<string, Object>; if (params && params.selectedValue) { this.selectedValue = params.selectedValue as string; } } } ​ // 页面B: 选择后返回 @Component struct SelectorPage { onSelect(value: string): void { // ✅ 返回并携带数据 router.back({ url: 'pages/PageA', params: { selectedValue: value } }); } build() { List() { ListItem() { Text('选项1') } .onClick(() => { this.onSelect('选项1'); }) } } }

4. RouterMode 模式

// ✅ Standard模式(默认): 每次都创建新实例 router.pushUrl({ url: 'pages/DetailPage' }, router.RouterMode.Standard); ​ // ✅ Single模式: 复用已有实例 router.pushUrl({ url: 'pages/DetailPage', params: { id: 2 } }, router.RouterMode.Single); // 如果DetailPage已存在,会复用并更新参数

5. 路由拦截

/** * 路由守卫 */ export class RouterGuard { /** * 需要登录的页面 */ private static authPages: string[] = [ 'pages/ProfilePage', 'pages/SettingsPage', 'pages/OrderPage' ]; /** * 跳转前检查 */ static async navigate(url: string, params?: Object): Promise<void> { // ✅ 检查是否需要登录 if (this.authPages.includes(url)) { const isLoggedIn = await this.checkLogin(); if (!isLoggedIn) { // 未登录,跳转到登录页 router.pushUrl({ url: 'pages/LoginPage', params: { redirect: url, // 登录后跳转回来 redirectParams: params } }); return; } } // 已登录或不需要登录,正常跳转 router.pushUrl({ url, params }); } private static async checkLogin(): Promise<boolean> { const token = await AppSettings.getInstance().getUserToken(); return token !== null && token !== ''; } } ​ // 使用路由守卫 Button('我的订单') .onClick(() => { RouterGuard.navigate('pages/OrderPage'); })

6. 路由工具类

/** * 路由工具类 */ export class RouterUtils { /** * 跳转到详情页 */ static goToDetail(id: number): void { router.pushUrl({ url: 'pages/DetailPage', params: { id } }); } /** * 跳转到编辑页 */ static goToEdit(item: Item): void { router.pushUrl({ url: 'pages/EditPage', params: { item: JSON.stringify(item) } // ✅ 复杂对象转JSON }); } /** * 安全返回(检查是否有上一页) */ static safeBack(): void { const length = router.getLength(); if (length > 1) { router.back(); } else { // 没有上一页,跳转到首页 router.replaceUrl({ url: 'pages/Index' }); } } /** * 清空路由栈并跳转 */ static clearAndGo(url: string): void { router.clear(); // ✅ 清空路由栈 router.pushUrl({ url }); } /** * 获取参数(类型安全) */ static getParams<T>(): T | null { const params = router.getParams(); return params ? params as T : null; } } ​ // 使用 RouterUtils.goToDetail(123); RouterUtils.goToEdit(item); RouterUtils.safeBack();

关键 API

1. 路由跳转

方法说明是否可返回
pushUrl跳转到新页面
replaceUrl替换当前页面
back返回上一页-
clear清空路由栈-

2. 获取信息

// ✅ 获取路由参数 const params = router.getParams(); ​ // ✅ 获取路由栈长度 const length = router.getLength(); ​ // ✅ 获取当前路由状态 const state = router.getState(); console.info('当前页面:', state.path); console.info('路由名称:', state.name);

实战案例

案例 1: 列表-详情跳转

// 列表页 @Component struct ItemList { @State items: Item[] = []; build() { List() { ForEach(this.items, (item: Item) => { ListItem() { Row() { Text(item.name).fontSize(16); } .width('100%') .padding(16) } .onClick(() => { // ✅ 跳转到详情 router.pushUrl({ url: 'pages/ItemDetailPage', params: { itemId: item.id } }); }) }) } } } ​ // 详情页 @Entry @Component struct ItemDetailPage { @State item: Item | null = null; private itemId: number = 0; aboutToAppear(): void { // ✅ 获取参数 const params = router.getParams() as Record<string, Object>; this.itemId = params.itemId as number; // 加载详情 this.loadDetail(); } async loadDetail(): Promise<void> { this.item = await ItemDao.findById(this.itemId); } build() { Column() { // 返回按钮 Row() { Image($r('app.media.ic_back')) .width(24) .height(24) .onClick(() => { router.back(); }) } if (this.item) { Text(this.item.name).fontSize(20); } } } }

案例 2: 登录后跳转回原页面

// 登录页 @Entry @Component struct LoginPage { private redirectUrl: string = ''; aboutToAppear(): void { const params = router.getParams() as Record<string, Object>; this.redirectUrl = params?.redirect as string || 'pages/Index'; } async onLogin(): Promise<void> { // 登录成功 await login(); // ✅ 跳转回原页面 router.replaceUrl({ url: this.redirectUrl }); } }

最佳实践

1. 参数传递

// ✅ 推荐:传递ID,详情页加载数据 router.pushUrl({ url: 'pages/DetailPage', params: { id: 123 } // 只传ID }); // ❌ 不推荐:传递大对象 router.pushUrl({ url: 'pages/DetailPage', params: { item: largeObject } // 对象太大 });

2. 错误处理

try { await router.pushUrl({ url: 'pages/DetailPage' }); } catch (err) { console.error('跳转失败:', err); promptAction.showToast({ message: '页面不存在' }); }

3. 生命周期

@Entry @Component struct MyPage { // ✅ 页面首次创建 aboutToAppear(): void { const params = router.getParams(); // 初始化数据 } // ✅ 页面重新显示(从其他页面返回时) onPageShow(): void { // 刷新数据 this.refreshData(); } // ✅ 页面隐藏(跳转到其他页面时) onPageHide(): void { // 保存状态 } }

常见问题

Q1: 返回时如何传递数据?

使用 router.back()的 params 参数,在上一页通过 getParams 获取。

Q2: 如何清空路由栈?

使用 router.clear()清空,然后 pushUrl 跳转。

Q3: 如何实现 Tab 内导航?

使用 Navigation 组件,而不是 router。

总结

路由导航要点:

✅ pushUrl 跳转,back 返回 ✅ params 传递参数 ✅ RouterMode 控制实例 ✅ 路由守卫鉴权 ✅ 工具类封装常用跳转

参考资料

  • Router API
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/7 8:00:16

雷科电力-REKE2760W电力电缆故障测距仪

一、概述&#xff1a;雷科电力-REKE2760W电力电缆故障测距仪用于电力电缆故障点的距离测量&#xff0c;具有波形易于识别、分辨率高、界面友好、同时支持触摸按键和机械按键、易于操作等特点。低压脉冲方式可以独立使用&#xff1b;在脉冲电流方式下需要和高压信号发生器配合使…

作者头像 李华
网站建设 2026/7/7 9:09:12

医疗健康领域私有化部署Qwen3-14B的安全考量

医疗健康领域私有化部署Qwen3-14B的安全考量 在医院信息科的深夜值班室里&#xff0c;一位医生正通过语音助手查询一名慢性肝病患者的五年检验趋势。系统迅速调取了分散在LIS、PACS和电子病历中的数据&#xff0c;生成了一份带有动态图表的趋势分析报告——整个过程耗时不到8秒…

作者头像 李华
网站建设 2026/7/7 2:30:17

利用AutoGPT镜像+GPU加速,打造超强AI执行代理

利用AutoGPT镜像GPU加速&#xff0c;打造超强AI执行代理 在智能系统日益追求“自主完成任务”的今天&#xff0c;我们正见证一场从“对话助手”到“行动代理”的范式转移。过去&#xff0c;用户需要一步步引导AI完成工作&#xff1a;先问“有哪些Python学习资源&#xff1f;”…

作者头像 李华
网站建设 2026/7/7 16:09:37

好写作AI:你的论文“电子榨菜”,专治表达“高血压”!

还在为导师那句“逻辑不清、表达随意”的评语深夜emo吗&#xff1f;是不是感觉自己的论文&#xff0c;明明数据扎实&#xff0c;一写出来却总像“学术草稿”&#xff0c;离“严谨”二字总有那么点“蜜汁距离”&#xff1f;别怀疑&#xff0c;你缺的可能不是想法&#xff0c;而是…

作者头像 李华
网站建设 2026/7/7 14:44:54

Seed-Coder-8B-Base支持多语言开发:Java、C#、Rust全面覆盖

Seed-Coder-8B-Base&#xff1a;多语言智能编码的轻量级基石 在现代软件开发日益复杂的背景下&#xff0c;一个熟悉的场景反复上演&#xff1a;开发者面对庞大的代码库和繁杂的API文档&#xff0c;迟迟无法下手&#xff1b;新人加入项目后&#xff0c;光是搞懂内部SDK的调用方式…

作者头像 李华
网站建设 2026/7/7 11:39:40

学校培训系统与企业培训软件是什么?主要有何区别?

学校培训系统与企业培训软件在功能和目标上各具特色&#xff0c;分别适应不同的受众需求。学校培训系统主要聚焦于教育机构&#xff0c;通过结构化的课程管理和学员评估&#xff0c;提升教学质量与效率。而企业培训软件则专注于员工职业发展&#xff0c;提供个性化学习路径和实…

作者头像 李华