当前位置: 首页 > news >正文

【HarmonyOS实战】 Navigation路由系统:页面跳转原来可以这么优雅

文章目录

    • 前言
    • 一、Navigation 的整体架构
    • 二、路由配置:route_map.json
    • 三、页面的 @Builder 函数
    • 四、主页:Navigation 容器
    • 五、页面跳转:pushPathByName
    • 六、子页面:NavDestination
      • 6.1 onReady:获取路由栈
      • 6.2 onWillAppear:页面即将显示
    • 七、返回:pageInfos.pop()
    • 八、NavDestination 的生命周期
    • 九、传参:携带数据跳转
    • 十、Navigation vs Router 对比
    • 总结

前言

HarmonyOS 有两套页面跳转方案:旧的Router(基于 URL 路由,官方不推荐在新项目使用)和新的Navigation(基于组件树的路由,官方推荐)。

这个项目用的就是Navigation。表面上看,它只是从主页跳到地图页的一行pushPathByName,但背后涉及路由注册、路由栈管理、NavDestination等一套完整机制。这篇文章把这套机制搞清楚。

项目预览

一、Navigation 的整体架构

Navigation(路由容器) ├── NavBar(默认展示内容,可选) │ └── 主页内容(pageBuilder) └── NavDestination × N(各路由页面) ├── GasStationPage └── 其他页面...

Navigation是路由的"宿主",所有子页面都在它的管理下。每个子页面用NavDestination包裹,类似 Android 的Fragment

核心对象:NavPathStack——路由栈,管理页面的入栈/出栈。

二、路由配置:route_map.json

使用 Navigation 之前,需要在资源文件里注册所有子页面:

// resources/base/profile/route_map.json{"routerMap":[{"name":"GasStationPage","pageSourceFile":"src/main/ets/pages/GasStationPage.ets","buildFunction":"GasStationPageBuilder","data":{"description":"this is gas station page"}}]}

字段说明:

字段作用
name路由名称(跳转时使用这个名字)
pageSourceFile页面文件相对路径
buildFunction该页面的@Builder函数名
data可选的自定义数据

提示:route_map.json文件要在module.json5里注册,否则不会生效。DevEco Studio 创建项目时通常已经自动配置好了。

三、页面的 @Builder 函数

每个NavDestination页面需要提供一个顶层的@Builder函数,这是路由系统的入口:

// GasStationPage.ets@BuilderexportfunctionGasStationPageBuilder(){GasStationPage();// 创建 GasStationPage 组件实例}@Componentstruct GasStationPage{// 页面内容...build(){NavDestination(){// 必须用 NavDestination 包裹// ...}}}

为什么要有GasStationPageBuilder

route_map.json里的buildFunction指定的就是这个函数名,Navigation 框架会通过这个函数来实例化页面。你可以理解为:这是系统调用你页面的"工厂函数"。

四、主页:Navigation 容器

// MainPage.ets@Entry@Componentstruct MainPage{pageInfos:NavPathStack=newNavPathStack();// 路由栈build(){Navigation(this.pageInfos){// 传入路由栈this.pageBuilder();// 主页内容}.title($r('app.string.car_life'))// 主页标题.width('100%').height('100%').backgroundColor($r('app.color.page_background'));}}

NavPathStack是路由栈对象,它负责管理页面的前进和后退。把它传给Navigation组件后,Navigation会根据栈的状态渲染对应的页面。

五、页面跳转:pushPathByName

// 主页点击加油站入口时跳转Row().onClick(()=>{this.pageInfos.pushPathByName('GasStationPage',true);})

pushPathByName(name, animated)参数说明:

  • name:路由名称,必须和route_map.json里的name一致
  • animated:是否开启跳转动画(true开启)

跳转后,GasStationPage被推入路由栈,用户看到的是地图页。

六、子页面:NavDestination

// GasStationPage.ets@Componentstruct GasStationPage{pageInfos:NavPathStack=newNavPathStack();// 子页面也维护一个路由栈引用build(){NavDestination(){// 页面内容...}.onReady((context:NavDestinationContext)=>{// 页面准备好时,获取路由栈引用this.pageInfos=context.pathStack;}).hideToolBar(true)// 隐藏工具栏.hideTitleBar(true)// 隐藏标题栏.height('100%').width('100%').onWillAppear(()=>{// 页面即将显示时执行初始化this.init().then(()=>{setTimeout(()=>{this.isShow=true;},Constants.TIME);});});}}

6.1 onReady:获取路由栈

.onReady((context:NavDestinationContext)=>{this.pageInfos=context.pathStack;})

onReady在页面挂载完成后调用,通过context.pathStack获取当前路由栈。子页面需要持有这个路由栈才能执行"返回"等操作。

6.2 onWillAppear:页面即将显示

.onWillAppear(()=>{this.init().then(()=>{setTimeout(()=>{this.isShow=true;},Constants.TIME);// 延迟1秒后显示底部弹窗});});

onWillAppear在页面即将出现在屏幕上时调用,适合在这里做数据初始化。这里:

  1. 调用init()初始化地图和数据
  2. 延迟 1000ms 后设置isShow = true,显示底部的加油站列表弹窗

延迟是为了让地图先加载完成,给用户更好的视觉体验。

七、返回:pageInfos.pop()

// 点击返回按钮Image($r('app.media.back')).onClick(()=>{this.pageInfos.pop();// 弹出当前页面,回到主页});

pop()将当前页面从路由栈中弹出,显示上一个页面。

八、NavDestination 的生命周期

导航到该页面: onReady → onWillAppear → onAppear → onShown 导航离开(返回): onHidden → onWillDisappear → onDisappear → onWillDestroy → onDestroy

常用的几个:

生命周期触发时机常用场景
onReady页面准备好后获取路由栈
onWillAppear页面即将显示数据初始化
onAppear页面完全显示启动动画
onHidden页面被遮挡(未销毁)暂停资源消耗
onDisappear页面销毁清理资源

九、传参:携带数据跳转

项目里跳转时传了true作为参数,这是动画控制。实际上pushPathByName可以携带业务数据:

// 携带数据跳转this.pageInfos.pushPathByName('GasStationPage',{stationId:'001',stationName:'中国石化AA站'});

在目标页面接收参数:

.onReady((context:NavDestinationContext)=>{this.pageInfos=context.pathStack;// 获取传入的参数letparams=context.pathStack.getParamByName('GasStationPage')[0];letstationId=(paramsasRecord<string,string>).stationId;})

十、Navigation vs Router 对比

特性NavigationRouter
推荐程度✅ 官方推荐(新项目)⚠️ 旧方案,不推荐
路由方式组件树路由(栈管理)URL 跳转
动画控制内置,可自定义有限
传参方式pushPathByName直接传URL 参数
子页面包装NavDestination@Entry页面
适合场景多页面复杂应用简单页面跳转

总结

Navigation 路由系统的工作流程:

  1. 注册:在route_map.json里登记子页面(路由名 + 文件路径 + Builder函数名)
  2. 容器:主页用Navigation(pageInfos)包裹,创建路由容器
  3. 子页面:用NavDestination包裹,提供@Builder入口函数
  4. 跳转pageInfos.pushPathByName('路由名', 参数)
  5. 返回pageInfos.pop()

下一篇讲权限申请——用户位置权限是怎么申请的,PermissionsUtil做了哪些事。

http://www.rkmt.cn/news/1459822.html

相关文章:

  • 2026 AI提效核心:构建人机协作协议的聚合平台实践
  • 长沙包包2026回收实测:添价收领衔5家平台横向对比,透明变现指南 - 薛定谔的梨花猫
  • 5分钟快速上手Janus-Pro-1B:从零开始部署你的首个多模态AI应用
  • 如何用EPubBuilder在线编辑器5分钟打造专业电子书
  • 微信小程序班级管理全套资源:含学生签到、作业提交、通知发布与后台管理源码
  • FunClip终极指南:3步掌握本地AI视频剪辑神器
  • 3分钟掌握微信小程序二维码生成:weapp-qrcode完全指南
  • 免费在线使用的去水印软件推荐|分场景梳理图片视频多类免费去水印实用工具
  • 洛雪音乐助手:三大音乐平台一键聚合,打造你的专属音乐库
  • 伺服电机力矩控制实现精确运动
  • 3个现代Anki模板主题:如何让记忆卡片变得美观又高效
  • 东营威固官方授权门店推荐:柏年超群北二路旗舰店专业贴膜 守护行车品质 - 速递信息
  • Jina Embeddings v2 Base DE常见问题解答:解决使用中的15个典型问题
  • 动态目标无缝追踪技术白皮书
  • 3步掌握WebPlotDigitizer:从图表图像到结构化数据的思维革命
  • 车辆动力总成六自由度振动优化Matlab实操包(含调试通过代码、仿真图与参数设置指南)
  • LLaMA.cpp生态新成员:BitCPM4-CANN-8B-gguf本地运行与优化技巧
  • 淡纹抗初老眼油哪款好?实测4款高性价比眼油直击眼周干纹黑眼圈 - 全网最美
  • 除了网卡,DPDK还能加速什么?手把手配置加密引擎和基带加速器
  • 七轴机械臂避障新思路:用Python+ROS2实现零空间控制,让末端不动也能灵活调整姿态
  • 告别SLAM跟踪丢失就卡死!用ORB-SLAM Atlas实现多地图无缝切换的保姆级解读
  • 别再死记硬背!泊松过程‘到达时刻’的条件分布,一个‘均匀分布’的比喻就讲透
  • 别再被JDK8的加密限制坑了!手把手教你两种方法搞定JCE策略文件(附最新下载地址)
  • 国产大模型开源现状与真实可运行实践指南
  • 3分钟快速解密网易云音乐NCM文件:ncmdumpGUI免费图形界面工具完全指南
  • Java 程序员第 41 阶段06:企业智能问答机器人落地,搭建内部智能客服系统,用户认证与权限管理
  • 系统架构设计师下午题选题策略:五选三怎么选最容易
  • 当技术遇见效率:重新思考百度网盘资源获取的智能路径
  • Carnice-V2-27B:基于Qwen3.6-27B的Hermes智能体模型完全指南
  • DeepSeek V4实测:推理一致性与指令鲁棒性深度解析