正确思路:
- 请求菜单数据,将token、session_id封装在Axios中
- 将菜单数据存储在vuex中,并设置一个标记,标志是否已经添加过动态路由(未添加为false)
- 路由守卫中请求菜单,递归转换菜单数据为路由对象
注意(1):
route.component = () => import(
/src/views${menu.path}.vue) 对 route.component = () => import(@/views${menu.path}.vue) 错
import Layout from '@/layout/index.vue'
import router from '@/router';
// 递归转换菜单数据为路由对象
export function generateRoutes(menuData) {
const routes = []
menuData.forEach(menu => {
const route = {
path: menu.path, //路径
name: menu.menuName, //名称
// 父组件为layout
component: Layout,
// component: () => import(`@/views${menu.path}.vue`),
children: []
}
// console.log("🚀 ~ generateRoutes ~ route:", route)
if (menu.children && menu.children.length > 0) {
route.children = generateRoutes(menu.children)
} else {
route.component = () => import(`/src/views${menu.path}.vue`)
// route.component = () => import(`@/views${menu.path}.vue`)
}
routes.push(route)
if(route && !router.hasRoute(route.name)){
router.addRoute(route) // 动态添加路由
}
})
return routes
// console.log("🚀 ~ generateRoutes ~ routes:", routes)
}
转换后的正确路由为:
const asyncRoutes = [
{
path: "/cloudPhone",
name: "云手机管理",
component: Layout,
children: [
{
path: "/cloudphone/list",
name: "云手机列表",
component: () => import("src/views/cloudphone/index.vue"),
},
],
},
{
path: "/user",
name: "用户管理",
component: Layout,
children: [
{
path: "user/list",
name: "用户列表",
component: () => import("src/views/user/list.vue"),
},
{
path: "/user/menu",
name: "菜单列表",
component: () => import("src/views/user/menu.vue"),
},
{
path: "/user/role",
name: "角色列表",
component: () => import("src/views/user/role.vue"),
},
],
},
{
path: "/app",
name: "应用管理",
component: Layout,
children: [
{
path: "/app/list",
name: "应用列表",
component: () => import("src/views/app/index.vue"),
},
],
},
{
path: "/job",
name: "任务管理",
component: Layout,
children: [
{
path: "/job/list",
name: "任务列表",
component: () => import("src/views/job/index.vue"),
},
],
},
];
4、添加路由,将标志设为true
// 获取动态路由并添加
console.log("🚀 ~ router.beforeEach ~ store.state.hasAuth1111:", store.getters.hasAuth)
if(!store.getters.hasAuth){
console.log("🚀 ~ router.beforeEach ~ store.state.hasAuth:", store.getters.hasAuth)
await store.dispatch('menu/GetUserMenu');
const addRoutes = generateRoutes(store.getters.menuData)
console.log("🚀 ~ router.beforeEach ~ addRoutes:", addRoutes)
addRoutes.forEach(route => {
router.addRoute(route);
});
console.log(router.getRoutes(), '查看现有路由')
// 重新导航到目标路由
next({ ...to, replace: true });
}else{
next();
}
注意(2):vuex中一定要写命名空间,namespaced:true,
***vuex太过复杂,已将项目重构,改为pinia