Harmony Next - 系统路由表

377 阅读3分钟

前言

在移动端开发中,当我们的开发项目随着迭代日益复杂时,模块解耦和路由表管理成为了我们不可或缺的优化方案,尤其是在使用组件化或模块化架构时。实现模块解耦的路由表可以帮助不同模块之间通过统一接口进行通信和导航,而不直接依赖彼此,从而提高可维护性和可扩展性。

在鸿蒙系统开发中,如果是 API version 12 以前的版本我们需要自己去处理模块之间的导入,从而实现跨模块的页面跳转。从 API version 12 开始,Navigation 组件支持使用系统路由表的方式进行动态路由。下面我们来看一下系统路由表的具体使用吧!

项目准备

既然我们是为了项目的模块解耦,那么除了 entry 模块我们就还需要创建几个模块来模拟模块解耦的效果。在这里我们创建了 moduleAmoduleB 两个示例模块,项目结构图如下:

截屏2024-11-06 15.15.21.png

Tips:command + N 选择模块选项就可以新建模块了,可以选择动态库(HSP)或静态库(HAR)。本例中创建的是两个静态库。

前期工作准备就绪,接下来看下具体如何实现吧!

系统路由表的实现步骤

总体来说,要实现系统路由表需要以下四个步骤:

  • 在目标模块创建 route_map.json 文件。
  • 在目标模块的 module.json5 文件中添加路由表配置。
  • 在跳转目标的页面中声明和 route_map.json 文件里一致的入口函数。
  • 在使用模块中导入跳转模块。

下面来分步详细的说明下。

第一步:创建路由表

假设我们 entry 模块的 index 页面要跳转到 moduleA 模块的 PageOne 页面,那我们需要在moduleA 模块的如下路径创建路由表 - route_map.json 文件:

截屏2024-11-06 15.23.16.png 路由表的内容如下:

{
  "routerMap": [
    {
      "name": "PageOne",
      "pageSourceFile": "src/main/ets/pages/PageOne.ets",
      "buildFunction": "PageOneBuilder",
      "data": {
        "description" : "这是页面 One"
      }
    }
  ]
}

配置说明如下:

配置项说明
name跳转页面名称。
pageSourceFile跳转目标页在包内的路径,相对src目录的相对路径。
buildFunction跳转目标页的入口函数名称,必须以@Builder修饰。
data应用自定义字段。可以通过配置项读取接口getConfigInRouteMap获取。

Tips:新建的 HAR 里的 resource 默认是没有 profile 文件夹的,需要我们手动创建。我们必须要创建 profile 文件夹,因为编译器默认该字段需符合'^[]profile:[09azAZ.]+]profile:[0-9a-zA-Z_.]+'的正则。

第二步:添加路由表配置

上一步,我们在moduleA 模块的如下路径创建路由表,那么为了路由表能生效,接下来要在 moduleA 模块的 module.json5 文件添加路由表:

{
  "module": {
    "name": "moduleA",
    "type": "har",
    "routerMap": "$profile:route_map", // 添加这一行
    "deviceTypes": [
      "default"
    ]
  }
}

第三步:声明页面的目标函数

声明完路由表,我们需要在相应页面声明与路由表一致的入口函数,且入口函数必须 @Builder 由修饰,否则编译报错:

// 跳转页面入口函数
@Builder
export function PageOneBuilder() {
  PageOne()
}

第四步:导入

最后一步,就是在需要使用的地方导入相应模块。比如本例中是 entry 模块需要跳转 moduleA 模块,那我们就需要在 entry 模块的 oh-package.json5 文件中导入 moduleA 模块:

"dependencies": {
  "modulea": "file:../moduleA"
}

传递参数

假如 moduleA 需要跳转 moduleB ,步骤同上。如果需要传递参数的话,示例代码如下:

// 路由表函数名如下:
"buildFunction": "PageTwoBuilder"
// 页面入口函数声明如下:
@Builder
export function PageTwoBuilder(param: Map<string, string>) {
  PageTwo({name: param.get("name")})
}
// 调用如下:
const map = new Map<string, string>();
map.set("name", "传递的参数");
this.pathStack.pushPathByName("PageTwo", map, true);