鸿蒙应用开发实战【74】— 子组件 router 导航:import 对比 getUIContext

发布时间:2026/11/5 10:40:04

鸿蒙应用开发实战【74】— 子组件 router 导航:import 对比 getUIContext 鸿蒙应用开发实战【74】— 子组件 router 导航import 对比 getUIContext本文是「号码助手全栈开发系列」第 74 篇持续更新中…开源社区https://openharmonycrossplatform.csdn.net前言在号码助手项目中页面导航路由跳转有两种实现方式import { router } from kit.ArkUI的模块导入以及this.getUIContext().getRouter()的实例获取。HomePage 等核心页面选择了 import 方式本篇深入分析两种方式的异同、选型依据和最佳实践。本文涵盖router 模块导入方式详解、getUIContext().getRouter() 实例方式详解、两种方式的对比分析、HomePage 选型决策解析、子组件路由导航模式、callback 错误处理、getUIContext 的其他能力getWindow、getDisplay 等、路由栈管理最佳实践。一、import { router } 方式1.1 模块导入这是号码助手中最常用的方式在文件顶部通过import引入router// HomePage.ets — import 方式import{router}fromkit.ArkUI;import{promptAction}fromkit.ArkUI;EntryComponentstruct HomePage{build(){Column(){// 页面内容...}}/** * 统一页面导航方法 */privatenavigate(url:string,params?:Recordstring,Object):void{router.pushUrl({url:pages/${url},params:params??{},}).then((){hilog.info(0x0000,HomePage,navigate success: %{public}s,url);}).catch((error:Error){hilog.error(0x0000,HomePage,navigate failed: %{public}s,error.message);promptAction.showToast({message:页面跳转失败:${error.message},});});}}1.2 FAB 按钮导航示例// HomePage.ets — FAB 悬浮按钮导航build(){Stack(){// 主内容区域this.MainContent()// FAB 悬浮按钮Image($r(app.media.ic_add)).width(56).height(56).position({bottom:24,right:24}).onClick((){this.showActionSheet();})}.width(100%).height(100%)}privateshowActionSheet():void{ActionSheet.show({title:选择操作,buttons:[{title:添加卡号,action:()this.navigate(AddCardPage),},{title:批量导入,action:()this.navigate(PasteImportPage),},{title:取消,action:(){},},],});}1.3 带参数导航// HomePage.ets — 统计卡片点击跳转privateonStatCardClick(status:string):void{this.navigate(StatusListPage,{status});}// 应用列表行点击privateonAppItemClick(app:AppBinding):void{this.navigate(AppDetailPage,{appId:app.id});}二、this.getUIContext().getRouter() 方式2.1 组件实例获取在自定义组件内部通过getUIContext()获取路由实例// 子组件中通过 getUIContext 导航Componentstruct AppListItem{Propapp:AppBinding|nullnull;build(){Row(){// 应用信息展示Text(this.app?.app_name??)Text(this.app?.status??)}.onClick((){this.navigateToDetail();})}privatenavigateToDetail():void{constrouterthis.getUIContext().getRouter();router.pushUrl({url:pages/AppDetailPage,params:{appId:this.app?.id??0,},}).catch((error:Error){console.error(navigate failed:,error.message);});}}2.2 在 Builder 中使用在Builder函数中也可以使用getUIContext()Componentstruct CardManagePage{BuilderCardItem(card:CardEntity){Column(){Text(card.label).fontSize(16).fontWeight(FontWeight.Bold)Text(this.formatPhone(card.phone_number)).fontSize(13).fontColor(#68708A)}.onClick((){// 在 Builder 中需要使用 getUIContextthis.getUIContext().getRouter().pushUrl({url:pages/CardDetailPage,params:{cardId:card.id},}).catch((error:Error){promptAction.showToast({message:跳转失败});});})}}三、两种方式深度对比3.1 核心特性对比特性import { router }getUIContext().getRouter()导入方式模块静态导入实例方法获取生命周期依赖无需要组件已挂载编译时检查有静态类型检查无运行时获取树摇优化支持不支持上下文绑定全局单例组件树上下文在 Builder 中使用直接使用需this.getUIContext()在非组件中使用可以用不可以用在回调中使用闭包捕获即可可能丢失this上下文3.2 为什么 HomePage 使用 import 方式HomePage 选择import { router }的核心原因因素import 方式getUIContext 方式调用频率高频多个导航点同等可用代码简洁度一行router.pushUrlthis.getUIContext().getRouter().pushUrl回调上下文无this丢失问题需注意this指向统一封装容易封装为全局工具NavigationUtil只能在组件内使用静态分析IDE 可提供导入提示无法静态分析// 结论HomePage 使用 import 封装为统一方法classNavigationUtil{staticpush(url:string,params?:Recordstring,Object):Promisevoid{returnrouter.pushUrl({url:pages/${url},params:params??{}});}}// 所有页面统一调用NavigationUtil.push(StatusListPage,{status:待换绑});3.3 何时使用 getUIContext 方式// 场景一自定义子组件中需要导航Componentexportstruct MyCustomButton{privatetargetUrl:string;build(){Button(跳转).onClick((){// 子组件中推荐使用 getUIContextthis.getUIContext().getRouter().pushUrl({url:this.targetUrl,});})}}// 场景二Builder 中需要导航BuilderfunctionGlobalActionButton(icon:Resource,url:string){Image(icon).width(48).height(48).onClick((){// Builder 函数中 this 不可用需通过参数传递})}四、getUIContext 的其他能力4.1 获取窗口信息getUIContext()不仅能获取 Router还能获取窗口、显示等信息Componentstruct CustomComponent{build(){Column(){// ...}}privategetWindowSize():void{constwindowthis.getUIContext().getWindow();// 获取窗口属性constpropertieswindow.getWindowProperties();hilog.info(0x0000,Component,window size: %{public}d x %{public}d,properties.windowRect.width,properties.windowRect.height);}privategetDisplayInfo():void{constdisplaythis.getUIContext().getDisplay();hilog.info(0x0000,Component,display dpi: %{public}d,display.densityDPI);}}4.2 getUIContext 可用方法方法返回类型用途getRouter()Router页面路由导航getWindow()Window窗口属性与操作getDisplay()Display屏幕显示信息getFont()Font字体管理getMediaQuery()MediaQuery媒体查询getFolder()Folder文件夹操作五、路由方法详解5.1 常用路由 API方法说明参数pushUrl(options)压入新页面{ url, params }replaceUrl(options)替换当前页面{ url, params }back(options?)返回上一页{ url, params? }getParams()获取当前页面参数无getState()获取路由栈状态无clear()清空路由栈无5.2 路由栈管理// 获取路由栈状态privatecheckRouteStack():void{conststaterouter.getState();hilog.info(0x0000,Router,route stack: index%{public}d, size%{public}d,state.index,state.size);}// 返回并传参privategoBackWithResult():void{router.back({url:pages/HomePage,params:{result:success},});}// 替换页面不保留返回privatereplaceToLogin():void{router.replaceUrl({url:pages/LoginPage,});}六、错误处理与最佳实践6.1 统一错误处理// common/utils/RouteUtil.ets — 统一路由管理import{router}fromkit.ArkUI;import{promptAction}fromkit.ArkUI;import{hilog}fromkit.PerformanceAnalysisKit;constTAGRouteUtil;exportclassRouteUtil{staticpush(url:string,params?:Recordstring,Object):Promisevoid{returnrouter.pushUrl({url:pages/${url},params:params??{},}).catch((error:Error){hilog.error(0x0000,TAG,pushUrl failed: url%{public}s, error%{public}s,url,error.message);promptAction.showToast({message:页面跳转失败请重试,duration:2000,});});}staticreplace(url:string,params?:Recordstring,Object):Promisevoid{returnrouter.replaceUrl({url:pages/${url},params:params??{},}).catch((error:Error){hilog.error(0x0000,TAG,replaceUrl failed: %{public}s,error.message);});}staticback(params?:Recordstring,Object):void{router.back({params:params??{}});}}6.2 子组件导航模式// 模式一回调给父组件推荐Componentstruct AppListItem{Propapp:AppBinding|nullnull;privateonItemClick?:(app:AppBinding)void;build(){Row(){Text(this.app?.app_name??)}.onClick((){if(this.onItemClickthis.app){this.onItemClick(this.app);}})}}// 父组件处理导航EntryComponentstruct AppListPage{build(){ForEach(this.apps,(app:AppBinding){AppListItem({app:app,onItemClick:(item:AppBinding){RouteUtil.push(AppDetailPage,{appId:item.id});},})})}}// 模式二子组件直接导航简单场景Componentstruct SimpleLink{privateurl:string;privateparams?:Recordstring,Object;build(){Text(查看详情).fontColor(#4F7CFF).onClick((){this.getUIContext().getRouter().pushUrl({url:this.url,params:this.params??{},});})}}小结要点import routergetUIContext.getRouter推荐场景模块导入静态 import实例方法获取工具类组件内导航直接使用this.getUIContext()子组件Builder 中直接使用需注意 this 上下文Builder统一封装容易封装不方便封装项目全局静态分析支持不支持开发体验HomePage 选型✅ 采用可选高频导航页面如果这篇文章对你有帮助欢迎点赞、收藏⭐、关注你的支持是我持续创作的动力相关资源openHarmony 跨平台社区https://openharmonycrossplatform.csdn.netHarmonyOS UI 上下文 API 文档https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-uicontext-0000001821000749HarmonyOS 路由 API 官方文档https://developer.huawei.com/consumer/cn/doc/harmonyos-references/router-0000001820880781
延伸阅读

更多相关文章

2026/10/27 11:20:20

紫光盘古50K开发板HDMI接口FPGA开发指南

1. 紫光盘古50K开发板与HDMI接口概述紫光同创盘古系列50K开发板是一款面向中高端FPGA应用的国产开发平台,采用核心板扩展板的设计架构。开发板搭载的PGL50H芯片属于紫光同创Logos系列FPGA,逻辑单元规模达50K,内置DDR3控制器和多组高速收发器&…

2026/11/4 7:19:28

鸿蒙应用开发实战【73】— 页面参数传递:params 对比 AppStorage

鸿蒙应用开发实战【73】— 页面参数传递:params 对比 AppStorage 本文是「号码助手全栈开发系列」第 73 篇,持续更新中… 开源社区:https://openharmonycrossplatform.csdn.net 前言 在号码助手项目中,页面间参数传递有两种主流…

2026/11/4 17:12:33

基于Boost.Asio构建C++通用异步任务调度器:线程池与定时任务实践

1. 项目概述与核心价值最近在重构一个老项目的后台服务,核心痛点在于大量混杂的I/O操作和定时任务把主线程卡得死死的,响应速度慢得像在爬。排查下来,发现之前的实现是“一个线程一把梭”——网络请求、数据库查询、日志写入、定时统计全挤在…

2026/11/5 10:38:55

Univer开源Web Office引擎:Canvas渲染与协同编辑实战解析

第一次看到Univer这个项目名字的时候,我下意识以为是哪个海外团队用“University”做的教育类产品。直到我翻完它的仓库和在线Demo,才发现自己差点错过一个好东西——这是一个把“在线电子表格、文档、幻灯片”全部做成开源引擎的Web Office项目&#xf…

2026/11/5 10:38:55

Foxmail数字签名与加密配置全指南:S/MIME证书实战落地

1. 邮件签名与加密不是“加个水印”或“点个锁图标”那么简单很多人第一次在Foxmail里找“签名”功能,点开设置就以为万事大吉——填上姓名、电话、公司logo,保存退出,邮件发出去带个固定落款,就觉得“搞定”。等真遇到客户问“你…

2026/11/5 10:38:55

LVS负载均衡优化:FWM标记与持久化服务实践

1. 为什么需要优化LVS调度?在企业级负载均衡场景中,Linux Virtual Server(LVS)作为四层负载均衡的经典解决方案,其性能表现直接影响着整个业务系统的稳定性。但在实际生产环境中,我们常常会遇到两个典型问题…

2026/11/5 10:38:55

用Python打造个人命令行工具集:CLI-Anything实战解析

1. 项目概述:当我把一切日常操作都赶进了终端1.1 从一个真实痛点说起先坦白一个让人脸红的事实:在我动手写 CLI-Anything 之前,我的电脑桌面和工作目录乱得像个菜市场。截图随手丢在桌面,下载的文档散落在各个文件夹,临…

2026/11/5 10:38:55

基于Nios II软核的FPGA电子钟设计与软硬协同实现

简介:面向FPGA与Nios II学习者及课程设计开发者,这份电子钟工程以Verilog与SOPC协同实现为核心,可用于理解软硬件划分、定时器计时和外设驱动方法。设计采用Qsys生成的1ms定时器计时,8位数码管显示时间,3个按键完成正常…

2026/11/5 10:33:54

LSM-Tree与StarRocks存储引擎深度解析

1. LSM-Tree存储引擎基础解析 LSM-Tree(Log-Structured Merge-Tree)是现代数据库系统中广泛采用的一种存储结构,其核心设计思想是通过顺序写入和后台合并来优化写性能。与传统的B树结构相比,LSM-Tree在写入密集型场景下能提供更高…

2026/11/4 12:38:23

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/5 0:02:07

多智能体协作系统架构设计与实践优化

1. 多智能体协作系统的时代背景2017年Transformer架构的诞生彻底改变了人工智能的发展轨迹。当行业还沉浸在单一大模型带来的性能突破时,Anthropic的研究团队已经将目光投向了更前沿的领域——如何让多个智能体通过协作产生超越单体能力的系统智能。这就像交响乐团中…

2026/11/5 0:02:07

大模型系统性入门实战指南:从原理到部署微调的全链路路线

提到大模型的系统性入门,我先说个结论:这事真不难,难的是资料太散、路线太多,今天这个框架明天那个工具,新人很容易在“收藏夹吃灰”和“教程看到一半放弃”之间反复横跳。市面上关于大模型的内容少说有几十万篇&#…

2026/11/5 0:02:07

鸿蒙文件系统沙箱机制解析与开发实践

1. 鸿蒙文件系统沙箱机制深度解析作为一名从Android转向鸿蒙开发的工程师,我深刻体会到文件系统访问是迁移过程中最先遇到的"拦路虎"。在Android上运行良好的文件读写代码,在鸿蒙真机环境却频频出现文件写入后神秘消失或直接抛出权限拒绝错误的…

2026/11/4 12:38:23

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑