当前位置: 首页 > 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.jsqmd.com/news/948300/

相关文章:

  • 西安市富士通将军中央空调维修师傅电话|各区金牌师傅,靠谱选欧米到家 - 欧米到家
  • 2026 AI提效核心:构建人机协作协议的聚合平台实践
  • 3个技巧让X-Mouse Controls窗口切换效率翻倍:深度解析Windows焦点跟随鼠标的实战方案
  • 简单任务用便宜模型,关键镜头上高质量模型:模型路由到底怎么把 AI 成本打下来
  • 企业AI知识库搭建:从文件向量化到权限感知RAG的实战方案
  • KeymouseGo:免费开源鼠标键盘自动化工具完全指南
  • 长沙包包2026回收实测:添价收领衔5家平台横向对比,透明变现指南 - 薛定谔的梨花猫
  • Video.js 视频列表插件:点选即播,自动续播下一个
  • Qwen3-32B-gs-A8W8量化模型性能评测:96%GSM8K准确率背后的秘密
  • PHP设计模式工厂模式详解
  • 【职场】你公司挂在墙上的使命愿景价值观,本质是一套人事物的操控系统
  • 5分钟快速上手Janus-Pro-1B:从零开始部署你的首个多模态AI应用
  • 3分钟掌握JetBrains IDE无限试用:开源重置工具终极指南
  • TinyLlama-1.1B-Chat-v0.1安全部署指南:保护AI对话系统的5个关键步骤
  • 避坑指南:Verilog写BMP图片时多出0D字节?详解二进制与文本模式区别
  • 2026年郑州地坪漆厂家全景横评:环保耐磨定制方案选购指南 - 优质企业观察收录
  • C#写的推箱子游戏源码,带关卡编辑器、操作回放和本地存档
  • 如何用EPubBuilder在线编辑器5分钟打造专业电子书
  • 微信小程序班级管理全套资源:含学生签到、作业提交、通知发布与后台管理源码
  • MusicFree插件终极指南:5分钟打造你的全能音乐播放器
  • 基于Python+Django的轻量化私有云盘系统:从零搭建安全可控的文件存储与共享平台
  • Gemma 4-31B编程能力实战:10个代码生成与调试示例
  • 新手避坑指南:用ArcGIS和SWAT2012做水文模拟,我在石羊河流域踩过的那些‘雷’
  • FunClip终极指南:3步掌握本地AI视频剪辑神器
  • 2026年江苏钢结构厂家:徐州门式钢结构/钢结构天桥/钢结构栈桥,钢板下料/钢板切割/预埋件钢板有实力的企业 - 品牌企业推荐师(官方)
  • 3分钟掌握微信小程序二维码生成:weapp-qrcode完全指南
  • 易语言乐玩插件实战:用《剑侠情缘》多开,手把手教你搞定多线程后台绑定(附源码)
  • 免费在线使用的去水印软件推荐|分场景梳理图片视频多类免费去水印实用工具
  • F28335毫秒级定时器驱动工程:LED闪烁、数码管倒计时、按键响应与蜂鸣反馈一体化示例
  • MATLAB小波图像拼接教学包:带GUI操作界面、多组实测图像与完整可运行代码