Vue-router-3.0.1 uses router.addRoutes () to set dynamic routing. Dynamic routing is invalid when the corresponding page is refreshed directly.

< H1 > vue-router-3.0.1 uses router.addRoutes () to set dynamic. Dynamic routing is invalid when the corresponding page is refreshed directly < / H1 >.

Overview of problems

vue-router-3.0.1 uses router.addRoutes () to set up dynamic routes, jumping from the page of non-dynamic routes (routes that existed at the time of router initialization) to the page of dynamically added routes, and everything is fine. However, after the page of the dynamically added route is refreshed (that is, the page corresponding to the dynamic route is refreshed and then routed to itself), the route matching fails and the page cannot be rendered.

detailed introduction

recently do a small project, vue-related dependent version such as:

    "vue": "^2.5.2",
    "vue-router": "^3.0.1",
    "vuex": "^3.0.1"

in the project, before the user logs in to the system, the initial default route is as follows:

/**
 * 
 */
export const staticRouters = [{
    path: "/",
    redirect: "/Home"
}, {
    path: "/Home",
    component: Wrapper,
    children: [{
        path: "",
        name: "Home",
        component: Home
    }],
    meta: {
        name: ""
    }
}, {
    path: "/DiscussZone",
    component: Wrapper,
    children: [{
        path: "",
        name: "DiscussZone",
        component: DiscussZone
    }],
    meta: {
        name: ""
    }
}, {
    path: "/Login",
    name: "Login",
    component: Login
}, {
    path: "/Register",
    name: "Register",
    component: Register
}]


/**
 * "" 
 */
export const myCenterRouter = [{
  path: "",
  redirect: "/MyCenter/myGame"
}, {
  path: "myGame",
  name: "myGame",
  component: MyGame,
  meta: {
    name: ""
  }
}, {
  path: "myPostings",
  name: "myPostings",
  component: MyPostings,
  meta: {
    name: ""
  }
}]

/**
 * 
 */
export const dynamicRouters = [{
    path: "/MyCenter",
    component: Wrapper,
    children: [{
        path: "",
        component: MyCenter,
        children: myCenterRouter
    }],
    meta: {
        name: ""
    }
}, {
  path: "*",
  name: "404",
  component: NotFound
}]

// 
export default new Router({
    routes: staticRouters
})

in vux, the userInfo field is set in state , where uid is the only ID, for the user to log in getters to calculate the available function modules and dynamic routes when the user is not logged in / logged in according to uid .

// vuex   store/index.js
...
state: {
    userInfo: {
        uid: "",
        role: ""
    }
},
...
getters: {
    // 
    userStatusMenu: state => {
        // vuexid
        return !state.userInfo.uid ? state.staticMenuList : state.staticMenuList.concat(state.dynamicMenuList)
    },
    // 
    userDynamicRouters: state => {
        // vuexid
        return !state.userInfo.uid ? [] : dynamicRouters
    }
},
mutations: {
    // /
    SET_USER_INFO(state, userInfo) {
        // state.userInfo = Object.assign({}, state.userInfo, userInfo)
        state.userInfo.uid = userInfo
    }
},

now you need to achieve the following functions:

before the user logs in, the system menu bar only has two functions: "Home" and "discussion area" and the corresponding initial route. When the user logs in to the system, the "personal center" module and its corresponding route are dynamically added.

personal implementation mechanism is as follows:

1. Before the user logs in, instantiate the initial route for the home page and discussion area

// router/index.js
...

export default new Router({
    routes: staticRouters
})

...

2. When the user logs in to the system, write the user uid to the browser sessionStorage (use its judgment when the later user forcibly refreshes the page), submit mutation , set the uesrInfo.uid field of stat e in vue x, at this time, the uid field changes, and the user menu bar (userStatusMenu) in getters will be recalculated. And calculate the dynamic new routes of the module userDynamicRouters .

3. vuex gettes calculate the routes that need to be dynamically added userDynamicRouters , then use router.addRoutes `( userDynamicRouters) to add dynamic routes to the initialized route instance object router`.

login() {
    this.$refs.loginForm.validate((valid) => {
        if (valid) {
            this.$store.commit("SET_USER_INFO", "1234567890")   // 1.vuexid
            sessionStorage.setItem("userUuid", "1234567890")    // 2.sessionidvuexid
            this.$router.addRoutes(this.userDynamicRouters)     // 3.
            this.$router.push("/Home")                          // 4.
        } else {
            this.$message.warning("")
            return false
        }
    })
}

so far, it is preliminarily solved to dynamically generate the function module entrance of the menu bar and add the dynamic routing function according to the login status of the user. After logging in, the dynamically added "personal center" module can also be routed normally.

but after the system page F5 or Ctrl+F5 is refreshed, the vuex and router instances of the refresh page will be reinitialized to the initial state, so the state.userInfo.uid and the new dynamic routes in vuex will be brushed out.

therefore, set the global routing guard router.beforeEach () in main.js, and rejudge the uid field stored in localStorage when the page refreshes. If it exists, the user logs in. If state.userInfo.uid in vuex is empty, the user refreshes the page after logging in, and the mutation is resubmitted to vuex at this time. And recalculate the dynamic route, and then addRotes () to the route instance router . As follows:

// 
router.beforeEach((to, from, next) => {
  let userUid = sessionStorage.getItem("userUuid")
  // sessionStorageuserUid
  if (userUid) {
    // vuestate.userInfo.uid
    if (!store.state.userInfo.uid) {
      store.commit("SET_USER_INFO", userUid)              // mutationstate.userInfo.uid
      router.addRoutes(store.getters.userDynamicRouters)  // 
    }
    next()
  } else {
    // 
    if (to.path.indexOf("/MyCenter") !== -1) {
      next("/Home")
    } else {
      next()
    }
  }
});

this solves the problem of dynamic routing failure when the page is refreshed.

however, But,However, I have encountered a pit, which is also the last question I want to ask in this post! Explain so much before, just want to describe the mechanism of their own implementation clearly, so that it is convenient for the god to take me and guide me!

the pits and problems I encountered

this pit is: I click the menu to jump to the dynamic routing module "personal Center" in the modules that existed when the router was initialized, such as "Home" and "discussion area". When you refresh the page and then jump to "personal Center", everything is fine! But, however, after entering the "personal Center", that is, routing to the dynamic increased dynamic routing, the page is refreshed directly in the dynamic routing page, but it cannot be routed properly, and the page is not rendered!
searched for a long time, google, du Niang looked around, but did not find a way to deal with it! My little brother is stupid, please give me some advice! Help me find out why?

Mar.07,2021

// 
router.beforeEach((to, from, next) => {
  let userUid = sessionStorage.getItem('userUuid')
  // sessionStorageuserUid
  if (userUid) {
    // vuestate.userInfo.uid
    if (!store.state.userInfo.uid) {
      store.commit('SET_USER_INFO', userUid)              // mutationstate.userInfo.uid
      router.addRoutes(store.getters.userDynamicRouters)  // 
    }
    next()  //***next({...to})***
  } else {
    // 
    if (to.path.indexOf('/MyCenter') !== -1) {
      next('/Home')
    } else {
      next()
    }
  }
});

the next () in the first if in the above code is changed to next ({.to})


do you have any advice? Thank you very much! Thank you!


how did I finally solve the problem? I encountered the same problem

.
Menu