鸿蒙中HMRouter的使用

260 阅读6分钟

概述

HMRouter是HarmonyOS上页面跳转的场景解决方案,主要解决页面间相互跳转的问题,开发者可以参考HMRouter使用说明进行安装配置与快速上手,本文主要以实际开发中的各项场景为例,介绍HMRouter路由框架的使用。HMRouter路由框架提供了下列功能特性:

  • 使用自定义注解实现路由跳转。
  • 支持HAR/HSP。
  • 支持路由拦截、路由生命周期。
  • 简化自定义动画配置:配置全局动画,单独指定某个页面的切换动画。
  • 支持不同的页面类型:单例页面、Dialog页面。

该框架底层对Navigation相关能力进行了封装,帮助开发者减少对Navigation相关细节内容的关注、提高开发效率,同时该框架对页面跳转能力进行了增强,例如其中的路由拦截、单例页面等。下文以页面跳转、弹窗提示、转场动效、数据加载、维测场景为切入点,介绍HMRouter路由框架的使用

说明文档长这个样子 官网没有 在gitee中gitee.com/harmonyos_s…

​编辑

1. HMRouter 简介

HMRouter作为应用内页面跳转场景解决方案,聚焦解决应用内ArkUI页面的跳转逻辑。

HMRouter底层对系统Navigation进行封装,集成了Navigation、NavDestination、NavPathStack的系统能力,提供了可复用的路由拦截、页面生命周期、自定义转场动画,并且在跳转传参、额外的生命周期、服务型路由方面对系统能力进行了扩展。

目的是让开发者在开发过程中无需关注Navigation、NavDestination容器组件的相关细节及模板代码,屏蔽跳转时的判断逻辑,降低拦截器、自定义转场动画实现复杂度,更好的进行模块间解耦。

2. 安装依赖

在模块目录下执行以下命令

ohpm install @hadss/hmrouter

3. 基础配置

1.修改工程的hvigor/hvigor-config.json文件,加入路由编译插件

{
  "dependencies": {
    "@hadss/hmrouter-plugin": "^1.0.0-rc.11"
    // 使用npm仓版本号
  },
  // ...其余配置
}

2.在使用到HMRouter的模块中引入路由编译插件,修改hvigorfile.ts

如果模块是Har则使用harPlugin(), 模块是Hsp则使用hspPlugin(), 模块是Hap则使用hapPlugin()

// ./hvigorfile.ts  工程根目录的hvigorfile.ts
import { appTasks } from '@ohos/hvigor-ohos-plugin';

export default {
  system: appTasks,
  plugins:[]
}

// entry/hvigorfile.ts  entry模块的hvigorfile.ts
import { hapTasks } from '@ohos/hvigor-ohos-plugin';
import { hapPlugin } from '@hadss/hmrouter-plugin';

export default {
  system: hapTasks,
  plugins: [hapPlugin()] // 使用HMRouter标签的模块均需要配置,与模块类型保持一致
}

// libHar/hvigorfile.ts  libHar模块的hvigorfile.ts
import { harTasks } from '@ohos/hvigor-ohos-plugin';
import { harPlugin } from '@hadss/hmrouter-plugin';

export default {
  system: harTasks,
  plugins:[harPlugin()]  // 使用HMRouter标签的模块均需要配置,与模块类型保持一致
}

// libHsp/hvigorfile.ts  libHsp模块的hvigorfile.ts
import { hspTasks } from '@ohos/hvigor-ohos-plugin';
import { hspPlugin } from '@hadss/hmrouter-plugin';

export default {
  system: hspTasks,
  plugins: [hspPlugin()]  // 使用HMRouter标签的模块均需要配置,与模块类型保持一致
}

3.1. 工程配置

在工程目录下的build-profile.json5中,配置useNormalizedOHMUrl属性为true

{
  "app": {
    "products": [
      {
        "name": "default",
        "signingConfig": "default",
        "compatibleSdkVersion": "5.0.0(12)",
        "runtimeOS": "HarmonyOS",
        "buildOption": {
          "strictMode": {
            "useNormalizedOHMUrl": true
          }
        }
      }
    ],
    // ...其余配置
  }
}

3.2. 初始化框架

在UIAbility或者启动框架AppStartup中初始化路由框架

export default class EntryAbility extends UIAbility {
  onCreate(want: Want, launchParam: AbilityConstant.LaunchParam): void {
    HMRouterMgr.init({
      context: this.context
    })
  }
}

4. 快速开始

4.1. 定义路由入口

HMRouter依赖系统Navigation能力,所以必须在页面中定义一个**HMNavigation**容器,并设置相关参数,具体代码如下:

Navigation的系统属性通过modifier传递,部分modifier不支持的属性使用options设置

@Entry
@Component
export struct Index {
  modifier: NavModifier = new MyNavModifier();

  build() {
    // @Entry中需要再套一层容器组件,Column或者Stack
    Column(){
      // 使用HMNavigation容器
      HMNavigation({
        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);
  }
}

⚠️ 注意:HomePage指的是Navigation进入的第一个路由页面。

4.2. 路由页面

@HMRouter注解使用在自定义组件struct上,且该自定义组件需要添加export关键字,用于将组件标记为路由页面,使其可以通过HMRouterMgr进行导航。

🎯 从HomePage页面跳转 到PageA页面

编辑

编辑

  • HomePage页面

    //HomePage.ets @HMRouter({pageUrl: 'HomePage'}) @Component struct HomePage { build() { Column() { Text('首页')

        Button("跳转到PageA").onClick(() => {
        HMRouterMgr.push({
            pageUrl: "/pageA"
          })
        })
      }
    }
    

    }

  • PageA页面

    //PageA.ets @HMRouter({ pageUrl: "/pageA" }) @Component export struct PageA { build() { Column() { Text("PageA").fontSize(50).fontWeight(FontWeight.Bold) Button("回退到HomePage").onClick(()=>{ HMRouterMgr.pop() }) } .height('100%') .width('100%') .justifyContent(FlexAlign.Center) } }

4.3. 路由传参

HMRouter路由传参支持多种形式,分为路径参数路由参数

  • 路径参数:拼接在pageUrl末尾
  • 路由参数:以对象的形式传递给目标页面

🎯 示例代码

从HomePage页面跳转到目标页面PageB,并传递 路径参数路由参数;

//HomePage.ets
Button("跳转到PageB").onClick(() => {
  HMRouterMgr.push({
    pageUrl:"/pageB?username=zhangsan&password=123456",	//路径参数
    param:{			//路由参数
      name:"小刚",
      age:20
    }
  })
})

在目标页面PageB中接收参数;

  • HMRouterMgr.getCurrentParam(HMParamType.urlParam)获取路径参数

  • HMRouterMgr.getCurrentParam(HMParamType.routerParam)获取路由参数

    //PageB.ets @HMRouter({ pageUrl: "/pageB" }) @Component export struct PageB { aboutToAppear(): void {

    //1.获取路径参数
    const urlParam = HMRouterMgr.getCurrentParam(HMParamType.urlParam) as Map<string, Object>
    if (urlParam) {
      const username = urlParam.get("username")
      const password = urlParam.get("password")
      console.log("用户名:" + username)
      console.log("密码:" + password)
    }
    
    //2.获取路由参数
    const student = HMRouterMgr.getCurrentParam(HMParamType.routeParam) as Student
    if (student) {
      console.log("姓名:" + student.name)
      console.log("年龄:" + student.age)
    }
    

    } }

4.4. 页面跳转并返回

有时候页面跳转后再返回,需要携带参数回原页面;如:从HomePage跳转到PageB,再从PageB返回到HomePage同时携带参数。

  • HomePage页面

    //HomePage.ets Button("跳转到PageB").onClick(() => { HMRouterMgr.push({ pageUrl: "/pageB?username=zhangsan&password=123456", param: { name: "小刚", age: 20 }, }, { onArrival: () => { //跳转完成 console.log("页面跳转完成") }, onResult: (popInfo: HMPopInfo) => { //接收返回参数:{"message":"success","data":{"id":100}} console.log("接收返回参数:" + JSON.stringify(popInfo.result)) } }) })

  • PageB页面

    //PageB.ets @HMRouter({ pageUrl: "/pageB" }) @Component export struct PageB { build() { Column() { Text("PageB").fontSize(50).fontWeight(FontWeight.Bold) Button("返回HomePage").onClick(() => { HMRouterMgr.pop({ param: { message: "success", data: { id: 100 } } }) }) } .height('100%') .width('100%') .justifyContent(FlexAlign.Center) } }

你学会了吗?

华为开发者学堂