错误代码
路由配置文件,默认拥有login和404页面,登录完成后我调用addRoute添加board路由,正常跳转页面。
// router.js
// 默认拥有的路由
const routes = [
{
path: "/login",
name: "登录页面",
component: () => import(/* webpackChunkName: "login" */ "../views/login"),
},
{
path: "*",
name: "404",
component: () => import(/* webpackChunkName: "404" */ "../views/404"),
},
];
export const routeOfBoard = [
{
path: "/board",
name: "board",
component: () => import(/* webpackChunkName: "board" */ "../views/board"),
},
];
登录页面,模拟登录成功逻辑
// 登录成功后添加路由,并跳转页面
if (true) {
routeOfBoard.forEach((route) => {
router.addRoute(route);
});
this.$router.replace({ name: "board" });
}
发现错误-1
登录成功后可以正常使用vue应用,但是页面刷新动态路由会丢失,进入404页面
尝试解决错误-1
尝试把路由信息同时存储到了vuex中去,如果在全局路由前置守卫中发现userRoute长度为0,代表用户进行了刷新,重新进行动态路由添加。
vuex示例代码
import Vue from 'vue'
import Vuex from 'vuex'
import router from '@/router'
Vue.use(Vuex)
export default new Vuex.Store({
state: {
userRoute: [], // userRoute不做持久化
},
getters: {
userRouteLength(state) {
return state.userRoute.length
},
},
mutations: {
setUserRoute(state, userRoute) {
state.userRoute = [...state.userRoute, ...userRoute]
},
},
actions: {
addUserRoute(context, userRoute) {
if (Array.isArray(userRoute)) {
userRoute.forEach(route => {
router.addRoute(route)
})
} else {
throw `添加的路由必须是数组`
}
context.commit('setUserRoute', userRoute)
},
},
})
路由前置守卫实例代码
注意路由前置守卫必须调用next方法,否则页面不会跳转
router.beforeEach((to, from, next) => {
const toPath = to.path.split('/')[1]
if (toPath === 'login') {
next()
} else {
if (!token) {
// ...
} else if (store.getters.userRouteLength === 0) {
store.dispatch('addUserRoute', routeOfBoard)
next({ ...to })
} else next()
}
})
发现错误-2
虽然进行了动态添加路由,但是页面刷新后还是进入了404页面。
我这时候认为可能是动态添加路由的过程是异步的,页面跳转先于路由添加执行,因此使用了await和定时器来解决,但是没有解决,仍然进入了404页面
尝试解决错误-2
最后去除了默认路由中的404,改为放到了动态路由中去,解决了刷新后添加了动态路由还是匹配到404页面的问题
const routes = [
{
path: '/login',
name: '登录页面',
component: () => import(/* webpackChunkName: "login" */ '../views/login'),
},
]
export const routeOfNotFound = {
path: '*',
name: '404',
component: () => import(/* webpackChunkName: "404" */ '../views/404'),
}
export const routeOfBoard = [
{
path: '/board',
name: 'board',
component: () => import(/* webpackChunkName: "board" */ '../views/board'),
},
routeOfNotFound,
]
总结
动态添加的路由,刷新后,优先级比在new VueRouter中初始化的路由的404通配路由优先级来的低,因此404路由不能放在初始化路由中