news 2026/7/17 5:29:37

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

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
鸿蒙应用开发实战【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}from'@kit.ArkUI';import{promptAction}from'@kit.ArkUI';@Entry@Componentstruct HomePage{build(){Column(){// 页面内容...}}/** * 统一页面导航方法 */privatenavigate(url:string,params?:Record<string,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|null=null;build(){Row(){// 应用信息展示Text(this.app?.app_name??'')Text(this.app?.status??'')}.onClick(()=>{this.navigateToDetail();})}privatenavigateToDetail():void{constrouter=this.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?:Record<string,Object>):Promise<void>{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{constwindow=this.getUIContext().getWindow();// 获取窗口属性constproperties=window.getWindowProperties();hilog.info(0x0000,'Component','window size: %{public}d x %{public}d',properties.windowRect.width,properties.windowRect.height);}privategetDisplayInfo():void{constdisplay=this.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{conststate=router.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}from'@kit.ArkUI';import{promptAction}from'@kit.ArkUI';import{hilog}from'@kit.PerformanceAnalysisKit';constTAG='RouteUtil';exportclassRouteUtil{staticpush(url:string,params?:Record<string,Object>):Promise<void>{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?:Record<string,Object>):Promise<void>{returnrouter.replaceUrl({url:`pages/${url}`,params:params??{},}).catch((error:Error)=>{hilog.error(0x0000,TAG,'replaceUrl failed: %{public}s',error.message);});}staticback(params?:Record<string,Object>):void{router.back({params:params??{}});}}

6.2 子组件导航模式

// 模式一:回调给父组件(推荐)@Componentstruct AppListItem{@Propapp:AppBinding|null=null;privateonItemClick?:(app:AppBinding)=>void;build(){Row(){Text(this.app?.app_name??'')}.onClick(()=>{if(this.onItemClick&&this.app){this.onItemClick(this.app);}})}}// 父组件处理导航@Entry@Componentstruct AppListPage{build(){ForEach(this.apps,(app:AppBinding)=>{AppListItem({app:app,onItemClick:(item:AppBinding)=>{RouteUtil.push('AppDetailPage',{appId:item.id});},})})}}// 模式二:子组件直接导航(简单场景)@Componentstruct SimpleLink{privateurl:string='';privateparams?:Record<string,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.net
  • HarmonyOS UI 上下文 API 文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-guides/arkts-uicontext-0000001821000749
  • HarmonyOS 路由 API 官方文档:https://developer.huawei.com/consumer/cn/doc/harmonyos-references/router-0000001820880781
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/7/17 5:28:50

ChatGPT日程规划稀缺资源包:含12个行业定制模板(研发/销售/医疗/教育)、Prompt工程校验表与响应延迟优化参数集

更多请点击&#xff1a; https://kaifayun.com 第一章&#xff1a;ChatGPT日程规划的底层逻辑与适用边界 ChatGPT 日程规划并非基于真实日历 API 或本地时序调度引擎&#xff0c;其本质是语言模型对用户自然语言指令的语义解析、上下文推理与结构化文本生成。模型通过训练数据…

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

可视化AI如何提升数学推导与教学效率

1. 项目概述&#xff1a;当数学推导遇上可视化AI数学推导过程中最痛苦的事情是什么&#xff1f;不是复杂的公式变换&#xff0c;而是面对满屏符号时大脑不得不进行的"图形脑补"。去年我在辅导学生线性代数时&#xff0c;亲眼看到他们对着特征值分解的推导步骤抓耳挠腮…

作者头像 李华
网站建设 2026/7/17 5:27:37

具身智能闭环系统:感知决策行动的工程化实践

1. 这本书为什么不是又一本“具身智能”概念汇编&#xff1f;“具身智能&#xff1a;从理论到实践”——光看标题&#xff0c;你大概率会下意识划走。过去三年&#xff0c;市面上打着“具身智能”旗号的新书、白皮书、行业报告摞起来能当板凳用&#xff0c;但翻开来&#xff0c…

作者头像 李华
网站建设 2026/7/17 5:25:16

基于缝制运动学与材料力学:慧拿智能模板机对柔性复合耗材的工艺纠错与精度优化机制研究

轻工柔性耗材缝制领域长期存在难以根治的工艺痛点&#xff1a;超细纤维、雪尼尔多层复合、高弹针织扫地机拖布在批量缝制中&#xff0c;普遍出现拉伸形变、圆弧轨迹畸变、层间错位、针距漂移、残余内应力褶皱等结构性缺陷。行业传统认知将问题归结为“人工操作误差”或“面料材…

作者头像 李华
网站建设 2026/7/17 5:20:43

世界动作模型WAM:超越VLA的动作智能新范式

1. 项目概述&#xff1a;这不是又一个“多模态”空泛概念&#xff0c;而是动作理解范式的实质性跃迁“超越 VLA&#xff1a;世界动作模型&#xff08;WAM&#xff09;从这五篇看起”——这个标题里藏着三个关键信号&#xff1a;第一&#xff0c;“VLA”不是随便提的&#xff0c…

作者头像 李华
网站建设 2026/7/17 5:20:26

C++日志库log4cplus:从核心原理到生产环境实战配置指南

1. 项目概述&#xff1a;为什么我们需要一个专业的C日志库&#xff1f;在C项目的开发与维护过程中&#xff0c;日志记录常常是一个容易被轻视&#xff0c;却又在关键时刻决定问题排查效率的核心环节。很多开发者&#xff0c;尤其是初学者&#xff0c;习惯使用std::cout或printf…

作者头像 李华