news 2026/7/21 6:03:05

鸿蒙多功能工具箱开发实战(四)-路由导航与页面跳转

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
鸿蒙多功能工具箱开发实战(四)-路由导航与页面跳转

鸿蒙多功能工具箱开发实战(四)-路由导航与页面跳转

前言

路由导航是移动应用开发的核心功能之一。本文将详细讲解HarmonyOS中的路由机制,包括页面注册、路由跳转、参数传递、返回处理等核心功能。

一、HarmonyOS路由机制概述

1.1 路由配置文件

HarmonyOS使用main_pages.json配置页面路由:

{"src":["pages/Index","pages/calculator/RelativeCalculator","pages/calculator/DateCalculator","pages/calendar/LunarCalendar"]}

重要规则

  • 所有页面必须在src数组中注册
  • 路径相对于entry/src/main/ets/
  • 不需要.ets后缀

1.2 路由API

HarmonyOS提供@ohos.router模块处理路由:

importrouterfrom'@ohos.router'// 页面跳转router.pushUrl({url:'pages/Detail'})// 带参数跳转router.pushUrl({url:'pages/Detail',params:{id:123,name:'test'}})// 返回上一页router.back()// 返回并传参router.back({params:{result:'success'}})// 替换当前页面router.replaceUrl({url:'pages/Login'})// 清空路由栈并跳转router.clear()router.pushUrl({url:'pages/Index'})

二、页面注册实践

2.1 创建新页面

创建entry/src/main/ets/pages/calculator/RelativeCalculator.ets

importrouterfrom'@ohos.router'@Entry@Componentstruct RelativeCalculator{build(){Column(){// 标题栏Row(){Text('←').fontSize(24).onClick(()=>{router.back()})Text('亲戚称呼计算器').fontSize(18).fontWeight(FontWeight.Bold).layoutWeight(1).textAlign(TextAlign.Center)Text(' ')// 占位.fontSize(24)}.width('100%').height(56).padding({left:16,right:16}).justifyContent(FlexAlign.SpaceBetween)// 内容区域Column(){Text('计算功能开发中...').fontSize(16).fontColor('#999999')}.layoutWeight(1).justifyContent(FlexAlign.Center)}.width('100%').height('100%')}}

图 1 计算工具页面

2.2 注册页面路由

entry/src/main/resources/base/profile/main_pages.json中添加:

{"src":["pages/Index","pages/calculator/RelativeCalculator"]}

三、路由跳转实现

3.1 基本跳转

importrouterfrom'@ohos.router'// 在工具卡片点击时跳转ToolCard({name:'亲戚称呼计算器',icon:'👨‍👩‍👧‍👦',description:'计算亲戚关系的称呼',color:'#4A90E2',onCardClick:()=>{router.pushUrl({url:'pages/calculator/RelativeCalculator'})}})

3.2 带参数跳转

// 跳转并传递参数router.pushUrl({url:'pages/calculator/DateCalculator',params:{mode:'range',// 计算模式defaultDate:'2024-01-01'}})// 目标页面接收参数@Entry@Componentstruct DateCalculator{// 获取路由参数privateparams=router.getParams()asRecord<string,Object>privatemode:string=this.params?.modeasstring||'single'privatedefaultDate:string=this.params?.defaultDateasstring||''build(){Column(){Text(`模式:${this.mode}`)Text(`默认日期:${this.defaultDate}`)}}}

3.3 路由模式

// Standard模式(默认):新页面入栈router.pushUrl({url:'pages/Detail',mode:router.RouterMode.Standard})// Single模式:如果页面已存在,移到栈顶router.pushUrl({url:'pages/Index',mode:router.RouterMode.Single})

四、页面返回处理

4.1 基本返回

// 返回上一页router.back()// 返回到指定页面router.back({url:'pages/Index'})

4.2 返回传参

// 详情页返回时传参@Entry@Componentstruct DetailPage{build(){Column(){Button('确认选择').onClick(()=>{router.back({params:{selectedValue:'选项A',selectedId:1}})})}}}// 上级页面接收返回参数@Entry@Componentstruct ListPage{// 监听页面显示aboutToAppear(){// 获取返回参数constparams=router.getParams()if(params?.selectedValue){console.log('用户选择:',params.selectedValue)}}}

4.3 使用onBackPressed拦截返回

@Entry@Componentstruct EditorPage{@StatehasUnsavedChanges:boolean=falsebuild(){Column(){// 编辑内容...}}// 拦截返回事件onBackPress():boolean{if(this.hasUnsavedChanges){AlertDialog.show({title:'提示',message:'有未保存的更改,确定要离开吗?',primaryButton:{value:'取消',action:()=>{}},secondaryButton:{value:'确定',action:()=>{router.back()}}})returntrue// 拦截返回}returnfalse// 不拦截}}

五、路由栈管理

5.1 获取路由栈信息

importrouterfrom'@ohos.router'// 获取当前路由栈长度letstackLength=router.getLength()console.log('路由栈长度:',stackLength)// 获取路由状态letstate=router.getState()console.log('当前页面:',state.name)console.log('页面路径:',state.path)

5.2 替换页面

// 替换当前页面(不会增加路由栈)router.replaceUrl({url:'pages/Login'})// 使用场景:登录成功后跳转主页// 此时用户按返回键不会回到登录页

5.3 清空路由栈

// 清空所有页面router.clear()// 常用于退出登录functionlogout(){// 清除用户数据clearUserData()// 清空路由栈并跳转登录页router.clear()router.replaceUrl({url:'pages/Login'})}

六、实际应用示例

6.1 通用标题栏组件

创建components/TitleBar.ets

importrouterfrom'@ohos.router'/** * 通用标题栏组件 */@Componentexportstruct TitleBar{@Proptitle:string=''@PropshowBack:boolean=trueonBackClick?:()=>voidbuild(){Row(){// 返回按钮if(this.showBack){Text('←').fontSize(24).onClick(()=>{if(this.onBackClick){this.onBackClick()}else{router.back()}})}else{Text('')// 占位.width(24)}// 标题Text(this.title).fontSize(18).fontWeight(FontWeight.Bold).layoutWeight(1).textAlign(TextAlign.Center)// 右侧占位Text('').width(24)}.width('100%').height(56).padding({left:16,right:16}).justifyContent(FlexAlign.SpaceBetween).backgroundColor('#FFFFFF').shadow({radius:2,color:'#1A000000',offsetY:1})}}

6.2 使用标题栏组件

import{TitleBar}from'../components/TitleBar'@Entry@Componentstruct RelativeCalculator{build(){Column(){// 标题栏TitleBar({title:'亲戚称呼计算器'})// 内容Column(){// 页面内容...}.layoutWeight(1)}.width('100%').height('100%')}}

6.3 路由工具类

创建common/RouterUtils.ets

importrouterfrom'@ohos.router'/** * 路由工具类 */exportclassRouterUtils{// 页面路径常量staticreadonlyPAGES={INDEX:'pages/Index',RELATIVE_CALCULATOR:'pages/calculator/RelativeCalculator',DATE_CALCULATOR:'pages/calculator/DateCalculator',LUNAR_CALENDAR:'pages/calendar/LunarCalendar'}/** * 跳转到指定页面 */staticpush(url:string,params?:Record<string,Object>):void{router.pushUrl({url:url,params:params||{}}).then(()=>{console.log('路由跳转成功:',url)}).catch((err:Error)=>{console.error('路由跳转失败:',err.message)})}/** * 替换当前页面 */staticreplace(url:string,params?:Record<string,Object>):void{router.replaceUrl({url:url,params:params||{}})}/** * 返回上一页 */staticback(params?:Record<string,Object>):void{if(params){router.back({params:params})}else{router.back()}}/** * 获取路由参数 */staticgetParams<T>():T|null{constparams=router.getParams()returnparams?(paramsasT):null}/** * 判断是否可以返回 */staticcanGoBack():boolean{returnrouter.getLength()>1}}

6.4 使用路由工具类

import{RouterUtils}from'../common/RouterUtils'// 跳转RouterUtils.push(RouterUtils.PAGES.RELATIVE_CALCULATOR,{mode:'edit'})// 返回RouterUtils.back({result:'success'})// 获取参数interfaceDateParams{mode:stringdefaultDate:string}constparams=RouterUtils.getParams<DateParams>()

七、路由动画

7.1 页面转场动画

// 在页面组件中定义转场动画@Entry@Componentstruct DetailPage{// 页面入场动画pageTransition(){PageTransitionEnter({duration:300}).slide(SlideEffect.Right)PageTransitionExit({duration:300}).slide(SlideEffect.Left)}build(){Column(){// 页面内容}}}

7.2 共享元素转场

// 列表页@Entry@Componentstruct ListPage{build(){Column(){Image($r('app.media.icon')).width(100).height(100).sharedTransition('shared_image',{duration:300}).onClick(()=>{router.pushUrl({url:'pages/Detail'})})}}}// 详情页@Entry@Componentstruct DetailPage{build(){Column(){Image($r('app.media.icon')).width(300).height(300).sharedTransition('shared_image',{duration:300})}}}

八、小结

本文详细讲解了HarmonyOS路由导航的实现,核心要点:

  1. ✅ main_pages.json 配置页面路由
  2. ✅ router.pushUrl() 页面跳转
  3. ✅ router.getParams() 获取路由参数
  4. ✅ router.back() 页面返回
  5. ✅ onBackPress() 拦截返回事件
  6. ✅ router.replaceUrl() 替换页面
  7. ✅ 路由工具类封装

下一篇文章将讲解主题配色与全局样式管理。


系列文章导航
下期预告:鸿蒙多功能工具箱开发实战(五)-主题配色与全局样式管理

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

数据工程师核心能力四问:延迟、变更、可信、架构

1. 为什么这4个问题比简历和证书更能筛出真数据工程师“数据工程师”这个头衔在招聘市场上已经快被用烂了。我见过简历写着“精通Airflow、Spark、Flink、Kubernetes”的候选人&#xff0c;现场白板画个端到端数据流图&#xff0c;连上游业务系统怎么触发ETL任务都说不清楚&…

作者头像 李华
网站建设 2026/7/21 5:59:42

Win10桌面便签工具的高效使用与团队协作指南

1. Win10桌面便签工具的核心价值解析在Windows 10环境下&#xff0c;桌面便签工具早已超越了简单的"电子便利贴"概念。我经手过上百个效率工具配置案例&#xff0c;发现90%的用户只发挥了这类工具20%的潜力。真正专业的桌面便签系统应该实现三大核心功能&#xff1a;…

作者头像 李华
网站建设 2026/7/21 5:58:50

商业简化策略:少即是多的实战解析

1. 项目概述&#xff1a;解码"少即是多"的商业哲学 "少即是多"这个看似矛盾的理念&#xff0c;在商业领域已经演变为一种高效的经营策略。最近与麦德龙前CEO蔡天乐的对话让我深刻体会到&#xff0c;这绝不仅仅是一句口号&#xff0c;而是经过实战验证的管理…

作者头像 李华
网站建设 2026/7/21 5:58:09

辛普森案庭审分析:证据规则与司法改革

1. 项目背景解析1995年1月30日&#xff0c;美国加州最高法院迎来了轰动全美的辛普森案第四日庭审。这起案件因其涉及名人、种族、司法公正等敏感议题&#xff0c;成为美国司法史上最具争议的刑事案件之一。作为法律从业者&#xff0c;我注意到这个案件至今仍被法学院作为经典案…

作者头像 李华
网站建设 2026/7/21 5:58:06

Python全栈开发100天速成计划:从基础到实战

1. 项目概述&#xff1a;Python全栈开发者的100天速成计划"100天代码&#xff1a;2023年完整的Python Pro训练营"是Udemy平台上最新推出的沉浸式编程课程&#xff0c;专为希望系统掌握Python开发技能的学员设计。这个训练营采用"每日一练"的紧凑学习模式&a…

作者头像 李华
网站建设 2026/7/21 5:57:35

Claude Code集成DeepSeek API:终端AI编程助手完整部署指南

如果你正在寻找一个既能在终端中高效工作&#xff0c;又能享受强大AI编程助手的解决方案&#xff0c;那么Claude Code与DeepSeek的结合绝对值得你深入了解。这不仅仅是另一个AI工具的简单介绍&#xff0c;而是关于如何将两个平台的独特优势整合到你的日常开发流程中。传统AI编程…

作者头像 李华