鸿蒙动态路由实现方案

背景

随着CSDN 鸿蒙APP 业务功能的增加,以及为了与iOS、Android 端统一页面跳转路由,以及动态下发路由链接,路由重定向等功能。鸿蒙动态路由方案的实现迫在眉睫。

实现方案

鸿蒙版本动态路由的实现原理,类似于 iOS与Android的实现原理,具体理论可以查看 iOS 动态路由实现 这篇博文,这边不在赘述,这边只阐述实现逻辑。

1、路由地址与页面绑定

为了让鸿蒙中的每个页面都有一个固定的URL地址,我们这边借助了三方框架 HMRouter,具体HMRouter的实现方案,可以查看文档

ts 复制代码
@HMRouter({ pageUrl: 'app://app.com/blog/detail' })
@Component
export struct BlogDetailPage {
}

2、动态路由注册与跳转

我们实现了一个Router类,该类来实现我们动态路由表存储以及跳转的所有逻辑。routers 中存放了所有已经注册的URL。

ts 复制代码
 class Router {
  /**
  *  保存了所有已注册的 URL
  *  结构类似 {"blog": {":blogId": {"_":callback}}}
  */
  private  routers:Map<string,CommonAllType>
 }

通过下面方法实现注册动态路由表routers

ts 复制代码
 /*
   * 添加路由到路由表
   * */
  private addURL(urlStr:string):Map<string,CommonAllType>{
    let pathComponents = this.pathComponentsFromURL(urlStr)
    let subRoutes = this.routers
    for (let pathComponent of pathComponents){
      if (!subRoutes.get(pathComponent)) {
        subRoutes.set(pathComponent,new Map())
      }
      subRoutes = subRoutes.get(pathComponent) as Map<string,CommonAllType>
    }
    return subRoutes
  }

例如注册如下路由:

ts 复制代码
 Router.registerURLPattern('https://blog.csdn.net/:us' ,(params)=> {
        
 })

注册到本地路由表routers中应该是如下所示

json 复制代码
{
    "https": {
        "blog.csdn.net": {
            ":us": {
                "_": function ( {...} )
            }
        }
    }
}

所有注册的路由,都是以这种方式存储在routers中,跳转时就会从路由表中查询匹配到的路由,来跳转。

当有路由跳转时,调用以下方法:

ts 复制代码
Router.openUrl('https://blog.csdn.net/weixin_36162680/article/details/124127748', {'isLogin':true})

跳转时,匹配到路由有,那么也会生成相应的路由参数,如下:

js 复制代码
{
    "un": "weixin_36162680",
    "id": "124127748"
}

3、动态路由重定向实现及远端路由表格式

路由重定向

对于移动端的路由重定向,实际上就是将一个路由转换为另一个路由,例如:
https://blog.csdn.net/:us

转换为:
app://app.com/blog/detail?us=xxx

远端路由表格式

一条路由规则,分为一个 Key 和对应的 Value,Key 为需要注册的路由(匹配规则),Value 中包含重定向的路由地址,或者需要拦截的参数等。

这里面的Key 必须是与鸿蒙中页面所绑定的路由地址。

js 复制代码
{
    "app://app.csdn.net/blog/detail": {
        "needLogin": true
    },
    "https://blog.csdn.net/:un": {
        "redirectUrl": "csdnapp://app.csdn.net/blog/detail"
    }
}

跳转时重定向逻辑

ts 复制代码
Router.registerURLPattern('https://blog.csdn.net/:us' ,(params)=> {
      //判断是否需要登录
      if (!UserTool.isLogin() && params.has(Router.routerNeedLogin)) {
        let needLogin = params.get(Router.routerNeedLogin) as boolean
        if (needLogin) {
          Router.login()
          return
        }
      }
      //判断是否需要重定向
      .....
    })
HMRouter 路由是否注册

在使用的时候,还有情况需要判断页面是否绑定了HMRouter

ts 复制代码
/*
   * hm_router是否注册
   * */
  static isRegisterHMRouter(urlStr: string) : boolean {
    let mapJsonValue = getContext().resourceManager.getRawFileContentSync('hm_router_map.json')
    let jsonStr: string = strUtils.uint8ArrayToStr(mapJsonValue)
    let jsonObj = JSON.parse(jsonStr) as object
    let routMapArray = jsonObj['routerMap'] as Array<object>
    if (!strUtils.isBlank(urlStr)) {
      try {
        let tempURL = Url.URL.parseURL(urlStr)
        let tempUrlStr = tempURL.protocol + '//' + tempURL.host + tempURL.pathname
        let found = false
        for (let value of routMapArray){
          let name = value['name'] as string
          if (name === tempUrlStr) {
            found = true
            break
          }
        }
        return found
      }
      catch (err){

      }
    }
    return false
  }

至此,基本路由跳转方案均已经实现,另外可以通过判断路由是否注册,来提示用户。

相关推荐
8931519601 小时前
《鸿蒙开发-鸿蒙教程-答案之书》组件margin左和右等于没偏?
harmonyos·鸿蒙·鸿蒙系统·鸿蒙开发·鸿蒙教程·鸿蒙答案之书·鸿蒙margin
小徐同学14182 小时前
BGP边界网关协议(Border Gateway Protocol)路由引入、路由反射器
运维·网络·网络协议·华为·智能路由器·信息与通信·bgp
m0_748245343 小时前
华为数据中心CE系列交换机级联M-LAG配置示例
服务器·华为·php
光芒Shine5 小时前
【HarmonyOS-开发指南】
harmonyos
xianKOG5 小时前
鸿蒙UI(ArkUI-方舟UI框架)-开发布局
harmonyos
觉醒法师5 小时前
HarmonyOS开发中模拟器TextInput表单类的无法输入中文字符问题
前端·javascript·华为·typescript·harmonyos
shaodong11235 小时前
鸿蒙安装HAP时提示“code:9568344 error: install parse profile prop check error” 问题现象
华为·harmonyos
轻口味5 小时前
【HarmonyOS NAPI 深度探索6】使用 N-API 创建第一个 Hello World 原生模块
c++·华为·harmonyos·napi·harmonyos-next
证卡识读张工5 小时前
中软高科鸿蒙Next身份证读卡SDK集成说明
华为·harmonyos·鸿蒙·鸿蒙系统