鸿蒙next 路由栈封装,在signle 模式下让它像前端路由一样使用

192 阅读2分钟

在我开发鸿蒙next系统时,自定义的返回功能发现一个前端无法忍受的弊端,router.back 之后back的页面传递的参数没了,这能忍受?

然后去查相关文档,好像都会有这个问题,目前论坛里找到的方案是通过代码的方式去避免这个问题,但我还是想通过前端的方式去实现一个路由栈的功能,这样能让页面在不同地方返回的时候能有对应的参数

其主体思想是创建一个数组,和鸿蒙路由栈同步,这样就可以很优雅的实现routerback功能,想怎么back怎么back,当然,后续也会更新其他逻辑,让这个功能块更好用

相关代码片段为:

//common.ets 我这个主要是放一些公共方法,供其他页面,组件调用


//定义路由列表数据项
class routerList {
  public url: string = '';
  public params: routerParamsType = {}

  constructor(url: string, params?: routerParamsType) {
    this.url = url;
    if (params) this.params = params
  }
}

//存路由栈
let r_list: routerList[] = [new routerList('pages/welcome/welcome')]//这里用来存你的进入app的第一个页面,根据自己需求修改

//页面跳转方式
function pushUrl(url: string, params?: routerParamsType) {
  if (params) {
    // params.prev_page_url = router.getState().path + router.getState().name
  }
  if (r_list.length < 30) {
    r_list.push(new routerList(url, params))
  } else {
    r_list.shift()
    r_list.push(new routerList(url, params))
  }
  router.pushUrl({
    url: url,
    params: params
  })
}

//路由返回,如果有携带参数,则返回上一层,并携带上参数
//路由返回特定地址,暂时只支持返回特定页面栈和返回上一页,暂时不指定返回页面层数,因为我这边暂时没这个需要,其实可以用返回特定页面栈实现这一功能
function routerBack(url?: string, params?: routerParamsType) {

  if (url && params) {
    //特定返回格式
    let needChangeIndex = -1;
    let index = r_list.length;
    r_list.map((v, i) => {
      if (v.url == url) {
        needChangeIndex = i
      }
    })
    r_list.splice(needChangeIndex, index - needChangeIndex);
    r_list.push(new routerList(url, params))
    router.pushUrl({
      url: url,
      params: params
    })
  } else {
    r_list.pop();
    let index = r_list.length;
    if (index == 0) {
      router.back()
    } else {
      router.back({
        url: r_list[index-1].url,
        params: r_list[index-1].params
      })
    }
  }

}

//清除所有路由栈
function routerClear() {
  r_list = []
  router.clear()
}

//路由替换
function routerReplace(url: string, params?: routerParamsType) {
  r_list.pop();
  r_list.push(new routerList(url, params))
  router.replaceUrl({
    url: url,
    params: params
  })
}

export {
pushUrl,
routerBack,
routerClear,
routerReplace
}

其中定义的routerParamsType我是做了一个大的集合定义,如下,

interface routerParamsType  {
  mobile?:string,
  psw?:string,
  link?:string,
  prev_page_url?:string,

}

//使用方法

//跳转新路由
pushUrl('pages/web/webPage',{
  link:'https://xxx.com?mobile='+this.mobile+'#/phoneNumInput'
})
//路由返回
//返回特定页面
routerBack('pages/login/login',{mobile:this.mobile,psw:this.psw})
//直接返回上一页
routerBack()

//接收页面参数
个人习惯用onpageShow 或者组件的aboutToAppear来实现初次加载,这个你根据你的需求去使用
const param = (router.getParams() as routerParamsType)
if(param?.mobile && param?.psw){
  this.mobile = param.mobile
  this.psw = param.psw
}

以上就是前端方式路由栈实现方式,我这个只适用于signle模式!!!