background

  • The applets history stack supports a maximum of 10 layers
  • When the applets business is more complex, it can easily exceed 10 layers.
  • After more than 10 layers, some models will not respond when clicked, and some models will have some unknown errors

To solve these problems, we introduce an infinite hierarchy routing scheme.

plan

First of all, I would like to make it clear that the original proposal was not put forward by me, but by a student with excellent academic performance in Tsinghua University. However, they are based on the WEPY framework, and since we are using MPVue, we have made changes to this scheme, and are not dependent on the framework.

Although it is a modified version, but the principle is the same, I will introduce the revised scheme.

A few key points:

  1. Within 9 layers (inclusive) : it is ok to go through the history stack of the applet itself, and update the logical stack when jumping, which is nothing to say
  2. Jump from layer 9 to Layer 10: You need to redirect layer 9 to the transit page and then jump from the transit page to layer 10
  3. NavigateTo redirectTo redirectTo redirectTo redirectTo redirectTo redirectTo redirectTo redirectTo
  4. NavigateTo navigateTo (jump) 10 layers above return: will return to the transit page, by the transit page judgment, specific return to which page, and then jump to the past
  5. Return from layer 10 to Layer 9: Return to the transit page and redirectTo the transit page to the layer 9 page
  6. Returns within 9 levels: It would have been nice to return directly and not update the logical stack, but it doesn’t matter because the logical stack is only used for transit pages
  7. Logical stack update mechanism:
    1. Update when jump, return to transit page
    2. When navigateTo update
    3. When redirectTo update
    4. ReLaunch the update
    5. NavigateBack when update

Here is:

  1. The user action
  2. Applets history stack
  3. Js logical stack: self-maintained JS routing stack
  4. Medium indicates the transfer page
  5. 1 2 3 4 5 6 7 8 9 A B C indicates different page paths
The user action Applets history stack Js logic stack The subsequent operation
1, 2, 3, 4, 5, 6, 7, 8 1, 2, 3, 4, 5, 6, 7, 8 1, 2, 3, 4, 5, 6, 7, 8 Skipping Page 9
1, 2, 3, 4, 5, 6, 7, 8, 9 1, 2, 3, 4, 5, 6, 7, 8, 9 1, 2, 3, 4, 5, 6, 7, 8, 9 Skipping page A
1 2 3 4 5 6 7 8 9 A 1, 2, 3, 4, 5, 6, 7, 8 1 2 3 4 5 6 7 8 9 A Page B
1 2 3 4 5 6 7 8 9 A B 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 9 A B Page C
1 2 3 4 5 6 7 8 9 A B C 1, 2, 3, 4, 5, 6, 7, 8 1 2 3 4 5 6 7 8 9 A B C return
1 2 3 4 5 6 7 8 9 A B 1 2 3 4 5 6 7 8 1 2 3 4 5 6 7 8 9 A B return
1 2 3 4 5 6 7 8 9 A 1, 2, 3, 4, 5, 6, 7, 8 1 2 3 4 5 6 7 8 9 A return
1, 2, 3, 4, 5, 6, 7, 8, 9 1, 2, 3, 4, 5, 6, 7, 8, 9 1, 2, 3, 4, 5, 6, 7, 8, 9 Return (logical stack not updated)
1, 2, 3, 4, 5, 6, 7, 8 1, 2, 3, 4, 5, 6, 7, 8 1, 2, 3, 4, 5, 6, 7, 8, 9 Return (logical stack not updated)
One, two, three, four, five, six, seven One, two, three, four, five, six, seven 1, 2, 3, 4, 5, 6, 7, 8, 9 Return (logical stack not updated)
One, two, three, four, five, six One, two, three, four, five, six 1, 2, 3, 4, 5, 6, 7, 8, 9 Return (logical stack not updated)
One, two, three, four, five One, two, three, four, five 1, 2, 3, 4, 5, 6, 7, 8, 9 Page 6
One, two, three, four, five, six One, two, three, four, five, six One, two, three, four, five, six Page 7
One, two, three, four, five, six, seven One, two, three, four, five, six, seven One, two, three, four, five, six, seven .

Careful readers may have noticed by now:

The previous jump and return operations above 10 levels update the logical stack, but return operations beyond 10 levels do not update the logical stack.

The reason:

This part is also the main transformation point of our original plan. Because up to level 10, all returns and jumps are taken over by the wechat system history stack.

We just have to make sure that the user updates when they jump through the API. Furthermore, the self-maintained logical routing stack is actually only used by the transit page.

This eliminates the need to register onUnload Hooks on each page to update routing information as it is returned in real time. Put all the logic for updating routing information in the API call layer. Don’t worry about business development.

Your code

Lib/navigator/navigator. Js (encapsulated jump method, History. The js code omitted)

. import History from'@/lib/navigator/History'Const MAX_LEVEL = 10 // Number of open page layers supported by the appletexportDefault class Navigator {// Static curtainPage ='/pages/curtain/curtain/main'Static _routes = new History({routes: [{url:' '}], correctLevel: MAX_LEVEL - 2 }) ... NavigateTo */ @makemutex ({namespace: globalStore, mutexId:'navigate'}) navigateTo (route) {console.log(route) {console.log('[Navigator] navigateTo:'// Update logical stack navigator._history. open({url: route.url})letCurPages = getCurrentPages() // If the value is smaller than the penultimate layer, open it directlyif(curPages. Length < max_level-1) {await navigator. _secretOpen(route) {wx.else if(curPages.length === MAX_LEVEL - 1) { const url = URL.setParam(Navigator.curtainPage, { url: {route.url}) await navigator._secretreplace ({url}) // wx.redirectto = {route}) await navigator._secretreplace ({url})else{await navigator._secretreplace (route) // wx.redirectto layer 10 page direct redirection}} /** * full history * @return {Array}
   */
  static get history () {
    returnNavigator._history.routes} /** * update route * @param {Object} config custom configuration, _config Fields and Comments */ static updateRoutes (routes = []) {this._history._routes = routes}... }Copy the code

Transfer page code/pages/curtain curtain/index. Vue

<template>
  <div class="main"></div>
</template>
<script>
import Navigator from '@/lib/navigate/Navigator'/ / query parametersletOpts = null // Whether the operation is a return operationlet isBack = false

exportDefault {onLoad (options) {// Cache parameter opts = options // Executes the onLoad life cycle, which is considered a jump or redirection operation isBack =false
  },
  onShow() {// The state of the logical stack will be updated in the jump function during the jump and redirect operationsif(! Const url = decodeURIComponent(opts.url) // Call decodeURIComponent(opts.url)true// Jump operationif (opts.type === 'navigateTo') {navigator._secretOpen ({url}) // Execute wx.navigateTo fairly directly, without updating logical stack // redirect}else if (opts.type === 'redirectTo') {navigator._secretreplace ({url}) // Perform wx.redirectto fairly directly, without updating the logical stack} // Return operation}else{// get the logical stackletRoutes = navigate. history // Routes = navigate. history Const operation = (routes. Length === navigator.maxlevel)?'redirectTo' : 'navigateTo'// Get the route to the page to returnlet preRoute
      if (operation === 'navigateTo'// Remove the last two elements from the logical layer: // Remove the last one because the last one needs to return // remove the last one because the logic stack preRoute = routes.splice(routes.length-2, 2)[0]}else{// Redirection only remove the last element preRoute = routes[routes.length-2] routes.splice(routes.length-1, } // update navigator.updateroutes (routes) This operation updates the logic stack Navigator[operation](preRoute)}} </script> <style lang="scss">
  .main {
    background-color: $white-color;
  }
</style>
Copy the code

That’s how it works, but there are a few caveats:

  • You need to call your own wrapped jump method in your business code

NavigateTo ({url: ‘XXX’}); navigateTo({url: ‘XXX’});

  • The JS logic stack should be updated in time (update timing as mentioned above), because this will directly affect the jump logic of the transfer page

The biggest advantage of this scheme is that there is no need to listen for the update of the logical stack when the page is unloaded, and there is no need to add the update logic stack code in every page.

OK, that’s all for this time. If you have any questions or better solutions, please leave a message for us to learn from each other.