本文主要介绍 vue 动态路由路径重复问题及刷新丢失页面问题的解决方案,记录生活记录bug。
问题一: 动态添加完路由,切换路由时,vue会警告路由名字重复。
原因: 动态路由添加时,调用 addRoutes(), 他只会帮我们注入路由,不会帮我们把前面的路由清掉,因此,就会重复添加了。
解决方案:
1.首先先定义一个创建路由实例的函数:
const createRouter = () =>
new Router({
routes: constantRouterMap,
});
- 重置路由方法
export function resetRouter(noHeader = true) {
// noHeader 这个是项目中的头部导航栏
const newRouter = createRouter(); // 重新创建一个路由实例
routers.matcher = newRouter.matcher; // 将新的路由实例的matcher属性赋给原来路由实例的matcher属性,即可实现原路由实例重置
if (noHeader) {
routers.addRoutes(headersRouter);
}
}
- 计算完动态路由后,插入路由中前进行路由重置
resetRouter(false);
// routers 是页面实例化的路由
routers.addRoutes(_.cloneDeep(DynamicRoutes));
问题二: 添加完路由后进行页面刷新后,动态添加的路由会消失,路径找不到
解决方案: 在页面路由权限判断页(permission.js)用了路由router.beforeEach可以直接判断路由刷新,在进行一次页面路由初始化派发。
router.beforeEach((to, from, next) => {
const hasToken = getToken()
if (hasToken) {
if (to.path === '/login') {
next({
path: store.state.permission.rootRoute
})
} else {
let isFirst = store.state.permission.isGetRoutes
store.dispatch('permission/initPage').then(() => {
if (!isFirst && to.path == '/home') {
next({
path: store.state.permission.rootRoute
})
} else {
next()
}
}).catch(() => {
next()
})
next()
}
} else {
if (whiteList.indexOf(to.path) !== -1) {
next()
} else {
next(`/login?redirect=${to.path}`)
}
}
})
问题三: 切换不同角色权限,之前动态添加的路由没有被清除,进入看到的还是上次进入的权限页面。
问题原因: 在vue 的 store 中没有清空,把 store 里的route 清空就好,
解决方案: 可以在退出登录设置,也可以在添加路由时清空,以下代码为 store 内 permission.js 添加动态路由前清空路由
const mutations = {
SET_ROUTES: (state, routes) => {
state.addRoutes = routes;
state.routes = constantRoutes.concat(routes);
},
RESET_ROUTES: (state, payLoad) => {
state.addRoutes = [];
state.routes = [];
}
};
generateRoutes({ commit }, roles) {
return new Promise(resolve => {
// 关键代码 == 添加路由前将路由重置为空
commit("RESET_ROUTES");
// 设置登录的路由权限
let accessedRoutes;
if (roles === 4) {
// 教师登录
accessedRoutes = teacherRouter;
}
if (roles === 3) {
// 学生登录
accessedRoutes = studentRouter;
}
commit("SET_ROUTES", accessedRoutes);
resolve(accessedRoutes);
});
下面是收集一下相关功能代码
定义一个创建路由的函数
// 定义一个创建路由的函数
const createRouter = () =>
new Router({
mode: "hash",
// mode: "history", // require service support
base: process.env.BASE_URL, // 路由基准地址 这是历史模式使用的 为了防止后端路径冲突
// scrollBehavior: () => ({ y: 0 }),
// routes: constantRoutes, // constantRoutes静态路由映射
// routes: [...constantRoutes, ...asyncRoutes], // 静态+动态 放在一起
routes: [...constantRoutes], // 只有静态 放在一起 动态路由后面按根据用户权限控制添加动态路由
});
重置路由实例的方法
export function resetRouter(noHeader = true) {
const newRouter = createRouter(); // 重新创建一个路由实例
routers.matcher = newRouter.matcher; // 将新的路由实例的matcher属性赋给原来路由实例的matcher属性,即可实现原路由实例重置
if (noHeader) {
routers.addRoutes(headersRouter);
}
}
3.动态添加路由
resetRouter(false);
inRouter.addRoutes(_.cloneDeep(DynamicRoutes));