网友真实露脸自拍10p,成人国产精品秘?久久久按摩,国产精品久久久久久无码不卡,成人免费区一区二区三区

小程序模板網

小程序無限層級路由方案(無框架依賴)

發布時間:2018-12-11 08:51 所屬欄目:小程序開發教程
  • 小程序歷史棧最多只支持10層
  • 當小程序業務比較復雜時,就很容易超過10層。
  • 當超過10層后,有的機型是點擊無反應,有的機型會出現一些未知錯誤

為了解決這些問題,我們引入了無限層級路由方案。

方案

首先聲明一下,最初方案并不是我提出的,是我司內部一位清華學霸提出的。但他們是基于wepy框架做的處理,由于我們用的是mpvue,所以對這個方案上做了修改,同時不依賴于框架。

雖然是改造版,但原理是一樣的,下面我來介紹一下修改后的方案。

幾個關鍵點:

  1. 9層(含9層)以內時 :走小程序自己的歷史棧就ok了,跳轉時候更新一下邏輯棧,這沒啥可說的
  2. 從9層跳轉10層 :需要把第9層重定向到中轉頁,再由中轉頁跳轉到10層
  3. 10層以后跳轉 :在navigateTo方法中處理,到10層之后,再跳轉就第10層頁面一直做redirectTo(重定向)操作了
  4. 10層以上返回 :會返回到中轉頁,由中轉頁判斷,具體返回到哪個頁面,然后navigateTo(跳轉)過去
  5. 從10層返回到9層 :返回到中轉頁,將中轉頁redirectTo(重定向)到第9層頁面
  6. 9層內的返回 :直接返回就好了,返回時候不會更新邏輯棧,但沒有關系,因為只有中轉頁才會用到邏輯棧
  7. 邏輯棧更新機制 :
    1. 跳轉、返回中轉頁時更新
    2. navigateTo時更新
    3. redirectTo時更新
    4. reLaunch時更新
    5. navigateBack時更新

圖示:

  1. 用戶操作
  2. 小程序歷史棧
  3. js邏輯棧:自行維護的js路由棧
  4. “中”表示中轉頁
  5. “1 2 3 4 5 6 7 8 9 A B C”表示不同的頁面路徑

之前跳轉操作和10層以上的返回操作都會更新邏輯棧,到了10層以內的返回操作就不會更新邏輯棧了。到這里細心的讀者可能已經發現:

原因:

這塊也是我們對原有方案的主要改造點。因為到了10層以內,所有的返回和跳轉都由微信系統歷史棧接管了。

我們只要保證用戶在通過api進行跳轉操作時更新就可以了。而且,自己維護的邏輯路由棧實際上只有中轉頁才會用到。

這樣也就不用在每個頁面都要注冊onUnload鉤子去實時更新返回時的路由信息了。把更新路由信息的邏輯都放到了api調用這一層。業務開發時完全不用關心。

示意代碼

lib/navigator/Navigator.js (自己封裝的跳轉方法, History.js代碼省略了)

...
import History from '@/lib/navigator/History'
const MAX_LEVEL = 10 // 小程序支持打開的頁面層數
export default class Navigator {
  // 中轉頁面路徑
  static curtainPage = '/pages/curtain/curtain/main'
  // 最大頁數
  static maxLevel = MAX_LEVEL
  // 邏輯棧
  static _history = new History({
    routes: [{ url: '' }],
    correctLevel: MAX_LEVEL - 2
  })
  
  ...
  
  /**
   * 打開新頁面
   * @param {Object} route 頁面配置,格式同wx.navigateTo
   */
  @makeMutex({ namespace: globalStore, mutexId: 'navigate' }) // 避免跳轉相關函數并發執行
  static async navigateTo (route) {
    console.log('[Navigator] navigateTo:', route)
    // 更新邏輯棧
    Navigator._history.open({ url: route.url })

    let curPages = getCurrentPages()
    // 小于倒數第二層時,直接打開
    if (curPages.length < MAX_LEVEL - 1) {
      await Navigator._secretOpen(route) // 就是調用wx.navigateTo
    // 倒數第二層打開最后一層
    } else if (curPages.length === MAX_LEVEL - 1) {
      const url = URL.setParam(Navigator.curtainPage, { url: route.url })
      await Navigator._secretReplace({ url })  // wx.redirectTo 到中轉頁,再由中轉頁跳轉到第10層頁面
    // 已經達到最大層數,直接最后一層重定向
    } else {
      await Navigator._secretReplace(route)    // wx.redirectTo 第10層頁面直接重定向
    }
  }
  
  /**
   * 完整歷史記錄
   * @return {Array}
   */
  static get history () {
    return Navigator._history.routes
  }
  
  /**
   * 更新路由
   * @param {Object} config 自定義配置,可配置項參見 _config 相關字段及注釋
   */
  static updateRoutes (routes = []) {
    this._history._routes = routes
  }
  
  ...
}
復制代碼

中轉頁代碼 /pages/curtain/curtain/index.vue

<template>
  <div class="main"></div>
</template>
<script>
import Navigator from '@/lib/navigate/Navigator'
// query參數
let opts = null
// 是否為返回操作
let isBack = false

export default {
  onLoad (options) {
    // 緩存參數
    opts = options
    // 執行onLoad生命周期,認為是跳轉或者重定向操作
    isBack = false
  },
  onShow () {
    // 跳轉、重定向操作時,邏輯棧的狀態會在跳轉函數里更新
    if (!isBack) {
      const url = decodeURIComponent(opts.url)
      // 再返回時認為是返回操作
      isBack = true
      // 跳轉操作
      if (opts.type === 'navigateTo') {
        Navigator._secretOpen({ url })      // 相當直接執行wx.navigateTo,不會更新邏輯棧
      // 重定向
      } else if (opts.type === 'redirectTo') {
        Navigator._secretReplace({ url })   // 相當直接執行wx.redirectTo,不會更新邏輯棧
      }
    // 返回操作
    } else {
      // 獲取邏輯棧
      let routes = Navigator.history
      // 如果10層之外的返回,用navigateTo操作
      // 如果是10層返回到9層,用redirectTo操作
      const operation = (routes.length === Navigator.maxLevel) ? 'redirectTo' : 'navigateTo'
      // 獲取要返回的頁面路由
      let preRoute
      if (operation === 'navigateTo') {
        // 移除邏輯層中后兩個元素:
        // 移除最后一個是因為要返
        // 移除倒數第二個是因為,跳轉到倒數第二個頁面時會重新插入邏輯棧
        preRoute = routes.splice(routes.length - 2, 2)[0]
      } else {
        // 重定向時只移除最后一個元素
        preRoute = routes[routes.length - 2]
        routes.splice(routes.length - 1, 1)
      }
      // 更新邏輯棧
      Navigator.updateRoutes(routes)
      // 執行自己包裝的跳轉、重定向方法,該操作會更新邏輯棧
      Navigator[operation](preRoute)
    }
  }
}
</script>
<style lang="scss">
  .main {
    background-color: $white-color;
  }
</style>
復制代碼

原理就是這樣,但是有幾點需要注意:

  • 業務代碼中需要調用自己封裝的跳轉方法

切記不要直接調用wx的api,也不要使用組件,這樣是沒法更新js邏輯棧的,正確跳轉方式如:Navigator.navigateTo({ url: 'xxx' })。

  • 跳轉時要及時更新js邏輯棧(更新時機如上所述),因為這會直接影響中轉頁的跳轉邏輯

這個方案最大的優點在于不用監聽頁面卸載時對邏輯棧的更新,無需在每個頁面里加入更新邏輯棧代碼。

OK,這次就介紹這么多,有問題或者有更好的方案,可以留言溝通,大家相互學習。


易優小程序(企業版)+靈活api+前后代碼開源 碼云倉庫:starfork
本文地址:http://www.xiuhaier.com/wxmini/doc/course/25005.html 復制鏈接 如需定制請聯系易優客服咨詢:800182392 點擊咨詢
QQ在線咨詢
AI智能客服 ×