vuex-路由问题

75 阅读1分钟
正确思路:
  1. 请求菜单数据,将token、session_id封装在Axios中
  2. 将菜单数据存储在vuex中,并设置一个标记,标志是否已经添加过动态路由(未添加为false)
  3. 路由守卫中请求菜单,递归转换菜单数据为路由对象

注意(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