vue dynamic routing

Links to the original text: https://segmentfault.com/a/1190000015419713

Update No. 2019.4.28:
In view of your many doubts, we have created a group of 1020135830 specially, which has many problems and exchanges.

Update on April 3, 2019:
I said why I couldn't come in to see the latest comments, but today I found it folded.
This tutorial is easy to understand if it is difficult.
Reference to write the routing table to the local, the back end returns to the user role to match this way, suitable for start-up: Write the route locally and request the user's role from the back end
The following is the original answer:

Hell is empty. Although the soil, but can heal wounds.

Preface

There are two ways to realize dynamic routing in vue project:
1. The front-end writes the routing well, and dynamically displays the routing according to the user's role and authority when logging in. (Front-end controls the routing)
Details can be found in the project of the big man in the flower pants. Hand handle... I watched the project for a long time before I understood a little bit of logic.
Because Dashen's dynamic routing has many layers of judgement, and interpolates various vuex, which makes Xiaobai's me confused. It inspires me a lot. It is this article that provides me with a lot of logic.
2. Routing table of current user's corresponding privileges comes from the background, and the front end receives the post-processing (back-end processing routing) through the interface.
These two methods have their own advantages and effects can be achieved. Our company is realized by the second method. The reason is that there is a special user center in the company project. The logic inside is very complex, and it is difficult to return to the front-end user rights. We are afraid that routing will be put in the front-end.
It's unsafe (as the company's backstage classmates said above). Okay, take the attitude of trying and exercising one's abilities.
We worked out the second method.

Today, we will talk about the idea of dynamic routing with backend routing table. Because vuex is partly used in the company's project, I sorted out the routing part from vuex to give you an inspiration. It is not an absolute solution, but a way of thinking.
github:https://github.com/Mrblackant...
Online View: http://an888.net/antRouter/#/...

Arrangement of Thoughts

The corresponding code for the following four steps is described below, and corresponds to

1. Backstage students return to a json-formatted routing table, and I use easymock to make a paragraph: Dynamic Routing Table For your reference.
2. Because the back-end students send back the string format, but the front-end needs a component object. Write a method to traverse it and convert the string into a component object.
3. Use vue-router's beforeEvery, addRoutes, and local Storage to achieve the above two steps.
4. The left menu bar is displayed according to the converted routing list.
General steps: intercept Routing - > backstage fetch Routing - > Save routing to local Storage (users log in only once from the background, the rest from the local fetch, so users, only exit in the login routing will update)

Code

1. Routing table

Each route uses component Layout, which is the overall page layout: left menu column, right page, so the first level of routing under child ren is your own page, meta contains the name of the route, and the corresponding icon of the route;
Because there may be multi-level menus, there will be nested child ren under child ren.
Routing is an array format
"data": {
    "router": [
      {
        "path": "",
        "component": "Layout",
        "redirect": "dashboard",
        "children": [
          {
            "path": "dashboard",
            "component": "dashboard/index",
            "meta": {
              "title": "home page",
              "icon": "dashboard"
            }
          }
        ]
      },
      {
        "path": "/example",
        "component": "Layout",
        "redirect": "/example/table",
        "name": "Example",
        "meta": {
          "title": "case",
          "icon": "example"
        },
        "children": [
          {
            "path": "table",
            "name": "Table",
            "component": "table/index",
            "meta": {
              "title": "form",
              "icon": "table"
            }
          },
          {
            "path": "tree",
            "name": "Tree",
            "component": "tree/index",
            "meta": {
              "title": "Tree",
              "icon": "tree"
            }
          }
        ]
      },
      {
        "path": "/form",
        "component": "Layout",
        "children": [
          {
            "path": "index",
            "name": "Form",
            "component": "form/index",
            "meta": {
              "title": "form",
              "icon": "form"
            }
          }
        ]
      },
      {
        "path": "*",
        "redirect": "/404",
        "hidden": true
      }
    ]
  }

2. Return the back-end "component": "Layout" to "component": Layout component object

Because of the emergence of multilevel routing, it is necessary to write a recursive traversal method to ensure that each component is converted into an object.
Because the string is returned in the background, the process of loading components should be encapsulated as a method (refer to the solution of Pants God here) and used in traversal; see the _import_development.js and _import_production.js files under the router folder in the project for details.
Layout's directory is different from other files'directories, so I deal with it separately in traversal. You can adjust it by yourselves.
const _import = require('./router/_import_' + process.env.NODE_ENV)//Method of getting components
import Layout from '@/views/layout' //Layout is an architecture component that is not returned in the background and is introduced separately in the file.

function filterAsyncRouter(asyncRouterMap) { //Traverse the route string passed in the background and convert it into component object
  const accessedRouters = asyncRouterMap.filter(route => {
    if (route.component) {
 **Bold text**     if (route.component === 'Layout') {//Layout Component Special Processing
        route.component = Layout
      } else {
        route.component = _import(route.component)
      }
    }
    if (route.children && route.children.length) {
      route.children = filterAsyncRouter(route.children)
    }
    return true
  })

  return accessedRouters
}

3. Use beforeEach, addRoutes, and local Storage to cooperate with the implementation

BeforeEast routing intercepts, enters the judgment, if discovers that there is no local routing data, then uses axios background to fetch once, after fetching, uses the local Storage to store, uses addRoutes to add routing dynamically.
ps: beforeEach is good or bad. One step carefully, it enters its dead circle. The browser tm crashes. It has to be judged at the beginning. When it gets the routing, it goes directly to next() and whispers.
global.antRouter is used to pass data to the left menu component for rendering.
import axios from 'axios'

var getRouter //Routes used to get backstage access

router.beforeEach((to, from, next) => {
  if (!getRouter) {//Without this judgment, the routing will fall into a dead circle.
    if (!getObjArr('router')) {
      axios.get('https://www.easy-mock.com/mock/5a5da330d9b48c260cb42ca8/example/antrouter').then(res => {
        getRouter = res.data.data.router//Background Get Routing
        saveObjArr('router', getRouter) //Storage routing to local Storage

        routerGo(to, next)//Executing Routing Jump Method
      })
    } else {//Get the routing from the local Storage
      getRouter = getObjArr('router')//Get Routing
      routerGo(to, next)
    }
  } else {
    next()
  }

})


function routerGo(to, next) {
  getRouter = filterAsyncRouter(getRouter) //Filtering routing
  router.addRoutes(getRouter) //Dynamic add routing
  global.antRouter = getRouter //Pass routing data to global variables and render sidebar menu
  next({ ...to, replace: true })
}

function saveObjArr(name, data) { //A Method of Storing Array Objects in localStorage
  localStorage.setItem(name, JSON.stringify(data))
}

function getObjArr(name) { //A Method of Obtaining Array Objects by localStorage
  return JSON.parse(window.localStorage.getItem(name));

}

4. Get the traversal route and render the left menu

The third part above assigns a value to the global. ant Router. This is a global variable (can be replaced by vuex). The menu is routed and rendered. Here is the layout section of the pants god. I will not paste the code here.

I hope you can make more corrections, especially for the part of routing interception, there should be a lot of optimization. Welcome to make corrections.

Tags: axios JSON Vue github

Posted on Wed, 28 Aug 2019 22:47:30 -0700 by machina3k