preface

  • Routing version,router.4x
"vue-router": "^ 4.0.0-0".Copy the code
  • Need to seerouter.3xLook here.Vue dynamic Routing (router.v3.x)
  • Source code addressvue3-dynamic-router.router4Basic andvue3Bound, so thisdemoIs to usevue3Written in grammar.

Used for dynamic routingrouter4theapi

The official documentation

GetRoutes () adds a route. AddRoute (name) adds a single route to a route. . RemoveRoute (name) Deletes a route. The added route is deleted when you deregister the route.

The whole process

1. The user logs in, obtains the route returned by the back-end, and saves itvuex

2, use,router.addRouteDynamic adding to routes

3, use,router.getRoutesRead the routing

4. When you log off,removeRouteExample Delete the added route

Implementation effect

Different user login displays different side route navigation

Introduction to core code

1. Simulated dynamic routing list

// Simulate the route from the back end
export const authRouter = [
  {
    path: "/allSeePage".name: "Visible to all.".component: "allSeePage".meta: {
      isSideBar: 1}}, {path: "/adminPage".name: "Administrator visible".component: "adminPage".meta: {
      isSideBar: 1}}]Copy the code

2. Log in to add a route

  • landing
const onSubmit = () = > {
// Trigger login, save information, add route
  store.dispatch("login", userInfo.value).then(() = > {
    console.log("Login jump")
    router.push({ path: "/home"})})}Copy the code
  • vuex– Add route, the route will disappear after refreshing, we need to add again
ADD_ROUTE(state) {
  console.log("Before adding route", router.getRoutes())
  // There are 3 routes before they are added
  if (router.getRoutes().length === 3) {
    let addRouterList = filterAsyncRouter(
      JSON.parse(JSON.stringify(state.userInfo.routerList)) // Make a deep copy here, otherwise there will be problems
    )
    addRouterList.forEach((i) = > {
      console.log("Add route", i)
      router.addRoute("home", i)
    })
  }
  console.log("After route is added", router.getRoutes())
}
Copy the code

3. Render menu

Router.getroutes () is a route object that has been added to router3.x. This method will change all layers into one layer

const routerList = router.getRoutes() // The route object obtained here is not the same as the route object of Router3. x
menuList.value = routerList.filter((route) = > {
  const isSidebar = route.meta.isSideBar ? route.meta.isSideBar : 0
  if (isSidebar) {
    return route
  }
})
Copy the code

4,vuexLogout – Deletes a route

/ / logout
logout({ commit, state }) {
  return new Promise((resolve) = > {
    console.log(state.userInfo.token, "Cancelled.")
    // Copy it
    const delRouterList = JSON.parse(
      JSON.stringify(state.userInfo.routerList)
    )
    // Delete the added route if the route is multi-level recursion.
    delRouterList.forEach((route) = > {
      router.removeRoute(route.name)
    })
    // Delete routes to clear user information
    commit("SET_USER_INFO", {
      userName: "".password: "".token: "".routerList: []
    })
    resolve("Logout success, clear route, user information")})}Copy the code

Routing hook functionbeforeEach

  • The vuEX route is refreshed. Procedure

  • code
router.beforeEach(async (to, from, next) => {
  // Get user information
  let { userInfo } = store.state
  const { username } = userInfo
  console.log("User roles", username ? username : "No landing")
  // There is user information
  if (username) {
    // Triggers the add route method, which determines whether it needs to be added
    await store.dispatch("addRoute")
    let { routerList } = userInfo
    // If to.name is a dynamic route, does anyone know of a better way to do this?
    if(! to.name) {// The to.name of the dynamic route is empty
      if (routerList.findIndex((i) = >i.path === to.path) ! = = -1) { next({ ... to,replace: true})}else {
        next("/ 404")}}else {
      console.log(28, router.getRoutes())
      next()
    }
  }
  // No user information
  else {
    // Without permission access, jump to no permission page/or login page
    // Check whether the interface needs to be jumped before jumping, otherwise it will enter an infinite loop
    if (to.path === "/login") {
      next()
    } else {
      ElMessage.error("Please login first!")
      next("/login")}}})Copy the code

Routing Component DynamicscomponentThe introduction of

  • filterAsyncRouterRoute lazy load import, route ofcomponentIt is bound to the front-end file path and supports multiple layers of nesting
  • Notice the introduction of theta hererouter3Different has been noted.
export const loadView = (view) = > {
  // Route lazy loading
  //return (resolve) => require([' @/views/${view} '], resolve) Router3
  return () = > Promise.resolve(require(`@/views/${view}`).default) / / router4 version
}
// Add components for permission routing asynchronously
export const filterAsyncRouter = (routeList) = > {
  return routeList.filter((route) = > {
    console.log(9, route)
    if (route.component) {
      // If it is not a layout component, it can only be a reference to the page
      // Assign the actual page to it using the lazy load function
      route.component = loadView(route.component)
      // Determine if there are child routes and recursively call yourself
      if (route.children && route.children.length) {
        route.children = filterAsyncRouter(route.children)
      }
      return true}})}Copy the code

In the pit of

Router. GetRoutes obtains only one routing layer. . 2. Never use router.options.routes to obtain routes because dynamic routing does not change. 3. After route F5 is refreshed, routes that are dynamically added before are lost. Need to add 4, 404 page, the hook function to determine the good. {path: ‘*’, redirect: ‘/404’}

Can refer to flower underpants big guy’s question

Write in the last

  • There may be a Bug in the code, hope to raise it in warehouse issues.
  • inbeforeEachIs there a better way to do that?
  • Code address -vue3-dynamic-router
  • Thank you for reading.