HMRouter 的简单使用

20 阅读5分钟

HMRouter 的简单使用

1.针对使用配置按照使用文档即可;链接如下:

OpenHarmony三方库中心仓

2.在引入库后,可能针对不同的module 配置有所差异,module 包分为 hap,har,hsp 大致三种格式;在module下 havigorfile.ts 中增加如下代码

//har library 
import { harPlugin } from '@hadss/hmrouter-plugin';
export default {
  plugins:[harPlugin()]      /* Custom plugin to extend the functionality of Hvigor. */
}
//hap
import { modulePlugin } from '@hadss/hmrouter-plugin';
export default {
  plugins: [modulePlugin()] // 使用HMRouter标签的模块均需要配置,与模块类型保持一致
}
//hsp
import { hspPlugin } from '@hadss/hmrouter-plugin';
export default {
  plugins: [hspPlugin()]     

执行跳转任务:

首先需要定义路由入口参考文档即可;下面代码是直接搬过来的;

@Entry
@Component
export struct Index {
  modifier: MyNavModifier = 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);
  }
}

跳转任务:

1.简单跳转携带参数:

首先在目标页面定义路径如下:

@HMRouter({ pageUrl: PAGE_ABOUT })
HMRouterMgr.push({pageUrl: PAGE_ABOUT,param:10})//方式一
HMRouterMgr.to(PAGE_ABOUT)
             .withParam(10)
             .push()//方式二

如果想要针对跳转路径进行统一的管理,可以创建一个.ets 文件,在内部定义静态常量如下(不用写在静态类中,如果写在类中,就无法找到路径,报错):

export const  PAGE_HOME:string = '/home'
export const  PAGE_ABOUT:string = '/about'
export const  PAGE_HOT:string = '/hot'
export const  PAGE_MAIN:string = '/main'

2.传递自定义的 bean

HMRouterMgr.push({pageUrl:PAGE_ABOUT,param:new UserBean(10,'小明')})

3.跳转并添加回调监听

         //跳转携带参数
          HMRouterMgr.push({ pageUrl: PAGE_ABOUT, param: '小明' }, {
            onResult(popInfo: HMPopInfo) {
              //这个是那个页面返回的路由信息
              // const srcName = popInfo.srcPageInfo.name
              //这个是跳转到那个页面的路由信息
              // const info = popInfo.info.name
              //接收的参数是String,
              // const result = popInfo.result as string
              //获取到返回值
              // const  result = popInfo.result as UserBean
              // console.log("-----------> params " + srcName + "..... result ... " + result.name+' .... '+result.age + '.... ' + info)
            }
            // ,
            // onArrival() {
            //   //属于跳转触发的时候执行的方法
            //   console.log("-----------> params arrive")
            // },
            // onLost() {
            //   //出现问题时报错
            //   console.log("-----------> params onLost")
            // }
          })

4.跳转到下个页面后,当前页面销毁;

      HMRouterMgr.to(PAGE_HOT)
        .withParam('小明')
         .replace()

注意:在使用 replace 的时候,如果在一级页面设置的回调监听,这个时候,在下级页面再次调用pop 方法回传数据将失效;在一级页面无法接受到数据;

 同时如果使用replace 跳转的时候,会导致返回出错有时;不清楚是否是模拟器问题;

5.点击退出当前页面

   HMRouterMgr.pop()
   //如果想要退出到指定页面
   HMRouterMgr.to(PAGE_MAIN)
          .withParam('小明')
          .pop()

设置拦截器:

首先创建拦截器的类

/**
 *   interceptorName: string;// 拦截器的名字
priority?: number; //拦截器的优先级
global?: boolean;//是不是全局拦截 如果设置了全局拦截器,就不需要再 指定页面的路径参数中配置该拦截器了
 */
@HMInterceptor({ interceptorName: JUMP_INFO_INTERCEPTOR })
export class JumpInfoInterceptor implements IHMInterceptor {
  handle(info: HMInterceptorInfo): HMInterceptorAction {
    let connectionInfo: string = info.type === 'push' ? 'jump to' : 'back to';
    // info.srcName//属于触发源,就是从那个页面开始跳的 路由信息
    // info.targetName//这个是目标源,也就是跳转到那个页面
    // info.type//属于触发的方法。例如是  push  pushAsync 对应的 type 都是push

    console.log('-----------> params JumpInfoInterceptor '+`${info.srcName} ${connectionInfo} ${info.targetName}  ${info.type}`)
    //设置了跳转拦截器
    switch (info.targetName){
      case PAGE_ABOUT:
        HMRouterMgr.to(PAGE_HOT)
          .withParam('小明')
          .replace()//目的就是把跳转的 about 页面给替换成 hot 页面
          // .push() 如果使用 push 的话,就会在返回的时候,一致在退出到 hot 页面
        // return HMInterceptorAction.DO_REJECT;//针对特殊的路径进行拒绝跳转
      return HMInterceptorAction.DO_TRANSITION
      default :
        return HMInterceptorAction.DO_NEXT;//不进行拦截进行跳转
    }
  }
}

然后添加拦截器

@HMRouter({ pageUrl: PAGE_ABOUT,interceptors:[JUMP_INFO_INTERCEPTOR] })

按照上述方式就可以进行跳转拦截,如果想要全局拦截,就更改global为true ,不需要在@HMRouter 中添加拦截器;

生命周期监听:

注意在生命周期拦截后,页面的生命周期方法只有aboutToAppear 和aboutToDisAppear会相应,其他的方法将被拦截,无法相应;

使用案例如下:

@HMLifecycle({ lifecycleName: 'PageDurationLifecycle' })
export class PageDurationLifecycle implements IHMLifecycle {
  private time: number = 0;
  module = new ARouterLifecycleModule()
   //重写方法即可
  onShown(ctx: HMLifecycleContext): void {
    this.time = new Date().getTime();
    // console.log('-----------> params  onShown ')
    this.module.status = 'onShown'
  }
    ....

}

页面中进行监听

 @HMRouter({ pageUrl: PAGE_ABOUT,lifecycle:'PageDurationLifecycle'})

    //获取到生命周期中的 module
  @Local module: ARouterLifecycleModule | null =
   (HMRouterMgr.getCurrentLifecycleOwner()?.getLifecycle() as PageDurationLifecycle).module
  // //监听状态值的改变
   @Monitor('module.status')
  private onModuleStatueChange(): void {
  console.log("-----------> params onModuleChange " + this.module?.status)
  }

module:

@ObservedV2
export class ARouterLifecycleModule{
  @Trace
  status?:string

}

对Router 跳转进行封装:

    因为 router 跳转传递参数,不能想 Android ARouter.withxxx 的方法传递多组,同时在获取数据的时候;也没有想 intent.getStringExtra()这种类似的获取方式;

    同时对应使用三方库的使用需要进行封装管理,为了避免后台更换跳转仓库,进行每个页面进行更换;

想法如下:

1.创建一个 Arouter.该类用于执行跳转功能,以及获取到页面传递数据功能;

2.创建一个 BundleModlue:该类内部是一个 map 集合,用于缓存跳转携带的参数;

3.创建一个 navigator 类:该类用于执行跳转任务,也就是最终的跳转方式,该类中包含了三方库的跳转方式;后期想要更换,直接替换该类即可;

4.创建一个数据接收管理类ARouterParamsModule:主要用于接收数据,然后将数据存储到 Bundle 中;并接收跳转需要的配置参数,例如 path,animator,skipAllInterceptor等;同时在跳转的时候,会将该类传递到 navigation 中,方便跳转的执行;

5.创建一个数据解析类ARouterParamsModule :该类主要用于解析传递的数据支持通过 getString,getNumber 等形式获取到数据,const bean = bundle.getCustomType('bean')获取创建自定义类型数据;