社区应用 最新帖子 精华区 社区服务 会员列表 统计排行
  • 246阅读
  • 2回复

[教程]微信小程序路由栈不能超过 10 的解决方案

楼层直达
z3960 
级别: 茶馆馆主
发帖
465977
飞翔币
115051
威望
4027
飞扬币
2433439
信誉值
8





微信小程序路由跳转有个隐藏的坑,就是 wx.navigateTo打开新页面,最多只能打开10个,超过10个之后就没反应,控制台也不会报错。

方案一:最粗暴…navigateTo不行,那就redirectTo
小程序路由跳转的方式有五种,分别是wx.navigateTo(打开新页面,新页面入栈)、wx.redirectTo(重定向,当前页面出栈,新页面入栈)、wx.navigateBack(返回,页面不断出栈,直到目标返回页)、wx.switchTab(切换tab页面,页面全部出栈,只留下新的 Tab 页面)、wx.reLaunch(页面全部出栈,只留下新的页面)

由此产生了第一种方式,当页面栈超过 10 时,直接用redirectTo。

但这样太粗暴了,显然很多场景是需要保留访问过的页面的,由此有了方案一的升级版。

方案一升级版:根据页面栈决定当前跳转方式
每次跳转先去页面栈中查找目标页面是否已经访问过,如果访问过则用wx.navigateBack返回,如果没有访问过则判断页面栈中是否已经有10个页面,有则用wx.redirectTo,没有则navigateTo
js code

class RouteMp {
  constructor(opt={}) {
    this.MAX_DEEP = opt.MAX_DEEP || 10
    this.IS_AUTO_BACK = opt.IS_AUTO_BACK || true
    this.PAGE_STACk = getCurrentPages()
  }

  _findPageInHistory(path) {
    const { PAGE_STACk } = this
    let delta = -1
    for (let i = 0; i < PAGE_STACk.length; i++) {
      if (PAGE_STACk.route === path) {
        delta = i + 1 // 目标页在栈中的位置
        break
      }
    }
    return delta
  }

  _dataToUrlQuery(data={}) {
    let query = '?';
    for (const prop in data) {
      if (data.hasOwnProperty(prop)) {
        const value = data[prop];
        query += `${prop}=${value}&`
      }
    }
    return query.replace(/&$/, '');
  }

  goPage(opt) {
    if (!opt) return new Error('缺少参数')
    if (opt && !opt.path) return new Error('缺少跳转目标path')
    const { PAGE_STACk } = this
    const pageStackLen = PAGE_STACk.length
    let { path, data } = opt
    let delta = this._findPageInHistory(path)
    path = '/' + path.replace(/^\//, '') + this._dataToUrlQuery(data)

    if (delta > -1 && this.IS_AUTO_BACK) {
      // 如果有目标页已经是被访问过的
      const backPage = PAGE_STACk[pageStackLen - delta]
      backPage.setData({data});
      wx.navigateBack({
        delta: pageStackLen - delta
      })
    } else {
      if (pageStackLen < this.MAX_DEEP) {
        wx.navigateTo({
          url: path
        })
      } else {
        wx.redirectTo({
          url: path
        })
      }
    }
  }

}

module.exports = RouteMp
复制代码

但是这样依然有问题,页面传参数变得无法统一,而且明明是前进页面,用户使用的时候很可能看着就是返回了几个页面。

方案二:在小程序页面栈之外维护多一个自己的逻辑栈
这个方案并非我们自己想到的,出处是某位清华学霸,我是在掘金-小程序无限层级路由方案看到的。

总的来说就是:vim

9层(含9层)以内时:走小程序自己的历史栈就ok了,跳转时候更新一下逻辑栈,这没啥可说的
从9层跳转10层:需要把第9层重定向到中转页,再由中转页跳转到10层
10层以后跳转:在navigateTo方法中处理,到10层之后,再跳转就第10层页面一直做redirectTo(重定向)操作了
10层以上返回:会返回到中转页,由中转页判断,具体返回到哪个页面,然后navigateTo(跳转)过去
从10层返回到9层:返回到中转页,将中转页redirectTo(重定向)到第9层页面
9层内的返回:直接返回就好了,返回时候不会更新逻辑栈,但没有关系,因为只有中转页才会用到逻辑栈
逻辑栈更新机制:
跳转、返回中转页时更新
navigateTo时更新
redirectTo时更新
reLaunch时更新
navigateBack时更新
关键词: 更新 小程序
 
我不喜欢说话却每天说最多的话,我不喜欢笑却总笑个不停,身边的每个人都说我的生活好快乐,于是我也就认为自己真的快乐。可是为什么我会在一大群朋友中突然地就沉默,为什么在人群中看到个相似的背影就难过,看见秋天树木疯狂地掉叶子我就忘记了说话,看见天色渐晚路上暖黄色的灯火就忘记了自己原来的方向。
级别: 超级版主
发帖
508260
飞翔币
113585
威望
222923
飞扬币
795747
信誉值
0

只看该作者 1 发表于: 11-27
来看一下
级别: 超级版主
发帖
508260
飞翔币
113585
威望
222923
飞扬币
795747
信誉值
0

只看该作者 2 发表于: 11-27
不错,了解了