鸿蒙应用开发之HMRouter路由框架

1.路由框架的演进

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

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

2. Navigation 组件结构

Navigation是路由容器组件,⼀般作为⾸⻚的根容器。Navigation组件主要包含导航⻚(NavBar)和⼦⻚
(NavDestination)。导航⻚由标题栏(Titlebar,包含菜单栏menu)、内容区(Navigation⼦组件)和⼯具栏
(Toolbar)组成,其中导航⻚可以通过hideNavBar属性进⾏隐藏。
导航⻚与⼦⻚以及⼦⻚之间可以通过路由栈操作进⾏切换,导航⻚不在路由栈( NavPathStack )中。
109.png

3.HMRouter 安装

在⼯程⽬录下输⼊下⾯命令,完成HMRouter包的安装。

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

4.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: [ /** 不需要扫描的模块 **/ ] })]
}

5. HMRouter 初始化

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

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

})

6. 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%")
  }
}

7.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)
  }
}

8.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 = undefined
  aboutToAppear(): void {
    const params = HMRouterMgr.getCurrentParam(HMParamType.urlParam) as Ma
    p<string, Object>
    this.username = params.get("username") as string
    this.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:string
  password:string
  constructor(username: string, password: string) {
    this.username = username
    this.password = password
  }
}
@HMRouter({ pageUrl: "PageA" })
@Component
export struct PageA {
  build() {
    Column() {
      Text("我是PageA")
      Button("跳转到PageB")
        .onClick(()=>{
          HMRouterMgr.push({pageUrl:"PageB",param:new User("zhangsan","12
            3")})
        })
    }.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 = undefined
  aboutToAppear(): void {
    const user:User = HMRouterMgr.getCurrentParam(HMParamType.routeParam)
    as User
    this.username = user.username
    this.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%")
  }
}

9.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: string
  password: string
  constructor(username: string, password: string) {
    this.username = username
    this.password = password
  }
}
@HMRouter({ pageUrl: "PageA" })
@Component
export struct PageA {
  @State fromPageBParams: string | undefined = undefined
  build() {
    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 User
                this.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 = undefined
  aboutToAppear(): void {
    const user:User = HMRouterMgr.getCurrentParam(HMParamType.routeParam)
    as User
    this.username = user.username
    this.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("⼩明","66
            6")})
        })
    }
    .width("100%")
    .height("100%")
  }
}

鸿蒙学习地址

posted @ 2025-11-14 11:04  leon_teacher  阅读(34)  评论(0)    收藏  举报