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

HarmonyOS路由导航方案演进:HMRouter基于Navigation封装,使用更方便

HMRouter 路由框架

路由框架的演进

随着HarmonyOS的不断演进,应用路由框架也在随之更新,从最初的router到Navigation,再到现在的HMRouter,路由框架的使用体验越来越方便、能力更强。

在这里插入图片描述

  • 从HarmonyOS 5.0开始,官方就不再推荐使用router进行路由导航了,进而推荐的是Navigation作为导航组件使用。
  • HMRouter是OpenHarmony三方库中提供的路由框架,基于Navigation封装而来,解决了Navigation使用不便的问题,同时对其功能进行了增强。

Navigation 组件结构

Navigation是路由容器组件,一般作为首页的根容器。Navigation组件主要包含导航页(NavBar)和子页(NavDestination)。导航页由标题栏(Titlebar,包含菜单栏menu)、内容区(Navigation子组件)和工具栏(Toolbar)组成,其中导航页可以通过hideNavBar属性进行隐藏。

导航页与子页以及子页之间可以通过路由栈操作进行切换,导航页不在路由栈( NavPathStack )中。

在这里插入图片描述

HMRouter 安装

在工程目录下输入下面命令,完成HMRouter包的安装。

  • 安装核心库
ohpm install @hadss/hmrouter
  • 安装高级转场动画库
ohpm install @hadss/hmrouter-transitions
  • 安装完成后,会在oh-package.json5文件中,添加依赖项,如下所示:

在这里插入图片描述

HMRouter 构建插件配置

由于HMRouter用到一些自定义注解(如@HMRouter等),默认的构建插件并不能识别这些注解。所以HMRouter提供了自定义构建插件,只需要简单配置即可。

  • 修改工程根目录下的 hvigor/hvigor-config.json 文件,加入路由编译插件。
"dependencies": {"@hadss/hmrouter-plugin": "^1.2.0-beta.0"  // 使用npm仓版本号
}
  • 修改工程根目录下的 hvigorfile.ts,使用路由编译插件。
import { appTasks } from '@ohos/hvigor-ohos-plugin';
import { appPlugin } from "@hadss/hmrouter-plugin";
export default {system: appTasks, /* Built-in plugin of Hvigor. It cannot be modified. */plugins: [appPlugin({ ignoreModuleNames: [ /** 不需要扫描的模块 **/ ] })]
}

HMRouter 初始化

在 EntryAbility中初始化路由框架,目的是让HMRouter持有UIAbility的上下文对象。

// 日志开启需在init之前调用,否则会丢失初始化日志
HMRouterMgr.openLog("INFO")
HMRouterMgr.init({context: this.context})

HMRouter 定义入口页面

在使用HMRouter时,一般会直接隐藏导航页,将第一个子页作为入口页面(首页),这样所有的页面都可以交给路由栈管理。

import { HMDefaultGlobalAnimator, HMNavigation } from "@hadss/hmrouter";
import { AttributeUpdater } from "@kit.ArkUI";@Entry
@Component
export struct Index {//Navigation的样式modifier: MyNavModifier = new MyNavModifier();build() {Column() {HMNavigation({//配置navigationId和入口页面(首页)navigationId: 'MainNavigation', homePageUrl: "HomePage",options: {standardAnimator: HMDefaultGlobalAnimator.STANDARD_ANIMATOR,dialogAnimator: HMDefaultGlobalAnimator.DIALOG_ANIMATOR,modifier: this.modifier}})}.height('100%').width('100%')}
}class MyNavModifier extends AttributeUpdater<NavigationAttribute> {initializeModifier(instance: NavigationAttribute): void {instance.hideNavBar(true)	//隐藏导航页}
}

使用HMRouter配置子页面不需要直接使用NavDestination,而是使用@HMRouter装饰@Component即可。代码人如下,将HomePage组件配置为子页。

@HMRouter({ pageUrl: 'HomePage' })
@Component
export struct HomePage {build() {Column() {Text("首页").fontSize(30)}.width("100%").height("100%")}
}

HMRouter 页面跳转与返回

如果需要切换到其他子页,只需要使用HMRouterMgr进行切换就可以了。HMRouterMgr封装了路由栈的功能。

需求:从HomePage切换到PageA,再从PageA切换到PageB,最后从PageB返回HomePage。

//HomePage.ets
import { HMRouter, HMRouterMgr } from "@hadss/hmrouter"@HMRouter({ pageUrl: 'HomePage' })
@Component
export struct HomePage {build() {Column() {Text("首页").fontSize(30)Button("跳转到PageA").onClick(() => {HMRouterMgr.push({pageUrl:"PageA"})})}.width("100%").height("100%")}
}
//PageA.ets
import { HMRouter, HMRouterMgr } from "@hadss/hmrouter"@HMRouter({ pageUrl: "PageA" })
@Component
export struct PageA {build() {Column() {Text("我是PageA")Button("跳转到PageB").onClick(()=>{HMRouterMgr.push({pageUrl:"PageB"})})}.width("100%").height("100%")}
}
//PageB.ets
import { HMRouter, HMRouterMgr } from "@hadss/hmrouter"@HMRouter({ pageUrl: "PageB" })
@Component
export struct PageB {build() {Column() {Text("PageB").fontSize(30)Button("返回到首页").onClick(() => {HMRouterMgr.pop({ pageUrl: "HomePage" })})}.width("100%").height("100%").justifyContent(FlexAlign.Center).alignItems(HorizontalAlign.Center)}
}

HMRouter 路由传参

HMRouter的路由传参分为URL参数和实体参数。

示例1:我们想要从PageA页面切换到PageB页面,同时传递url参数**"username=lisi&password=123"**给PageB页面。

  • 在PageA中使用HMRouterMgr.push(“PageB?username=lisi&password=123”)切换到目标页面同时携带参数。代码如下
//PageA.ets
import { HMRouter, HMRouterMgr } from "@hadss/hmrouter"@HMRouter({ pageUrl: "PageA" })
@Component
export struct PageA {build() {Column() {Text("我是PageA")Button("跳转到PageB").onClick(()=>{HMRouterMgr.push({pageUrl:"PageB?username=lisi&password=123"})})}.width("100%").height("100%")}
}
  • 在PageB页面中使用HMRouterMgr.getCurrentParam(HMParamType.urlParam)获取url参数,需要注意的是返回值为Map<string, Object>类型。
//PageB.ets
import { HMParamType, HMRouter, HMRouterMgr } from "@hadss/hmrouter"@HMRouter({ pageUrl: "PageB" })
@Component
export struct PageB {@State username: string | undefined = undefined@State password: string | undefined = undefinedaboutToAppear(): void {const params = HMRouterMgr.getCurrentParam(HMParamType.urlParam) as Map<string, Object>this.username = params.get("username") as stringthis.password = params.get("password") as string}build() {Column() {Text("PageB").fontSize(30)Text(this.username+":"+this.password).fontSize(20)Button("返回到首页").onClick(() => {HMRouterMgr.pop({ pageUrl: "HomePage" })})}.width("100%").height("100%")}
}

示例1:我们想要从PageA页面切换到PageB页面,同时传递实体参数**new User("zhangsan“,"123")**给PageB页面。

  • 在PageA页面中使用HMRouterMgr.push({pageUrl:“PageB”,param:new User(“zhangsan”,“123”)}) 跳转页面并传递参数。
import { HMRouter, HMRouterMgr } from "@hadss/hmrouter"class User{username:stringpassword:stringconstructor(username: string, password: string) {this.username = usernamethis.password = password}
}@HMRouter({ pageUrl: "PageA" })
@Component
export struct PageA {build() {Column() {Text("我是PageA")Button("跳转到PageB").onClick(()=>{HMRouterMgr.push({pageUrl:"PageB",param:new User("zhangsan","123")})})}.width("100%").height("100%")}
}
  • 在PageB页面中使用HMRouterMgr.getCurrentParam(HMParamType.routeParam) as User 获取实体参数。
@HMRouter({ pageUrl: "PageB" })
@Component
export struct PageB {@State username: string | undefined = undefined@State password: string | undefined = undefinedaboutToAppear(): void {const user:User = HMRouterMgr.getCurrentParam(HMParamType.routeParam) as Userthis.username = user.usernamethis.password = user.password}build() {Column() {Text("PageB").fontSize(30)Text(this.username+":"+this.password).fontSize(20)Button("返回到首页").onClick(() => {HMRouterMgr.pop({ pageUrl: "HomePage" })})}.width("100%").height("100%")}
}

HMRouter 返回传参

页面跳转完成后再返回到原页面时,携带参数到原页面。此时使用HMRouterMgr.push()中添加onResult()回调处理返回的数据。

示例:从PageA切换到PageB再返回到PageA,再PageA中接收PageB返回时携带的参数。

  • 在PageA中HMRouterMgr.push()回调中添加onResult()回调,用于处理从上一个页面返回的结果,代码如下。
//PageA.ets
import { HMPopInfo, HMRouter, HMRouterMgr } from "@hadss/hmrouter"export class User {username: stringpassword: stringconstructor(username: string, password: string) {this.username = usernamethis.password = password}
}@HMRouter({ pageUrl: "PageA" })
@Component
export struct PageA {@State fromPageBParams: string | undefined = undefinedbuild() {Column() {Text("我是PageA")if (this.fromPageBParams) {Text("从PageB返回的数据:" + this.fromPageBParams)}Button("跳转到PageB").onClick(() => {HMRouterMgr.push({ pageUrl: "PageB", param: new User("zhangsan", "123") },{onResult: (popInfo: HMPopInfo) => {const  user = popInfo.result as Userthis.fromPageBParams = user.username+":"+user.password}})})}.width("100%").height("100%")}
}
  • 在PageB中HMRouterMgr.pop()回调中添加param参数,代码如下。
import { HMParamType, HMRouter, HMRouterMgr } from "@hadss/hmrouter"
import { User } from "./PageA"@HMRouter({ pageUrl: "PageB" })
@Component
export struct PageB {@State username: string | undefined = undefined@State password: string | undefined = undefinedaboutToAppear(): void {const user:User = HMRouterMgr.getCurrentParam(HMParamType.routeParam) as Userthis.username = user.usernamethis.password = user.password}build() {Column() {Text("PageB").fontSize(30)Text(this.username+":"+this.password).fontSize(20)Button("返回PageA").onClick(() => {HMRouterMgr.pop({ pageUrl: "PageA",param:new User("小明","666")})})}.width("100%").height("100%")}
}

HMRouter页面绑定生命周期

IHMLifecycle是HMRouter框架中的页面生命周期接口,定义了页面在不同状态下的回调方法,这些回调方法的触发时机与NavDestination生命周期函数保持一致。

在这里插入图片描述

给页面绑定生命周期

在这里插入图片描述

http://www.xdnf.cn/news/1450675.html

相关文章:

  • 【软考架构】嵌入式系统及软件
  • Shadcn UI – 开发者首选的高性能、高定制化 React 组件库
  • Flutter之riverpod状态管理详解
  • 第1章 Jenkins概述与架构
  • ⸢ 肆 ⸥ ⤳ 默认安全:安全建设方案 ➭ b.安全资产建设
  • HTTP性能优化
  • Rust 文件操作终极实战指南:从基础读写到进阶锁控,一文搞定所有 IO 场景
  • 设计模式3 创建模式之Singleton模式
  • 大数据工程师认证推荐项目:基于Spark+Django的学生创业分析可视化系统技术价值解析
  • 基于 EasyExcel + 线程池 解决 POI 导出时的内存溢出与超时问题
  • 如何简单理解状态机、流程图和时序图
  • Docker学习记录
  • 记一次 Nuxt 3 + pnpm Monorepo 中的依赖地狱:`@unhead/vue` 引发的致命错误
  • 封边机高级设置密码解锁指南:技术解析与安全操作建议
  • k8s基础(未完待续)
  • doubletrouble: 1靶场渗透
  • ubuntu-24.04.3-live-server连接不上xhell
  • 当数据库宕机时,PostgreSQL 高可用在背后做了什么?
  • 探索 PostgreSQL 和 MySQL 之间的主要差异和相似之处,找到满足您项目需求的最佳数据库解决方案。
  • jQuery的$.Ajax方法分析
  • 低代码高效搭建应用,轻松应对多场景需求
  • 低代码选型避坑指南:告别封闭与绑定,星图云开发者平台定义开放灵活新标准
  • 3D 房地产地图 Web 应用
  • 从0到1搭建某铝箔智慧工厂网络:5G与WiFi 6助力智能制造
  • 渐变背景色和渐变字体颜色的实现方法
  • GPT-5冷酷操盘,游戏狼人杀一战封神!七大LLM狂飙演技,人类玩家看完沉默
  • 学习日记-SpringMVC-day49-9.4
  • 卫星通信+地面网络融合 Sivers半导体毫米波技术打通智慧交通最后一公里
  • DevOps平台选型指南:破解研发效率瓶颈,适配金融/政务/国产化场景的5大关键指标
  • E-E-A-T与现代SEO:赢得搜索引擎信任的完整策略