actions.js
// 动态路由后端返回的demo数据 提示:父路由必须在子路由的前面
const demoAsyncRoutes = [
{
id: 1,
pid: 0,
path: '/nested',
name: 'Nested',
hidden: false,
alwaysShow: true,
component: 'layout/Layout',
redirect: '/nested/menu1/menu1-1',
meta: '{ "title": "nested", "icon": "nested" }'
},
{
id: 2,
pid: 1,
path: 'menu1',
name: 'Menu1',
component: 'nested/menu1/index',
hidden: false,
alwaysShow: true,
meta: '{ "title": "menu1" }'
},
{
id: 3,
pid: 2,
path: 'menu1-1',
name: 'Menu1-1',
component: 'nested/menu1/menu1-1',
hidden: false,
alwaysShow: true,
meta: '{ "title": "menu1-1" }'
},
{
id: 4,
pid: 1,
path: 'menu2',
name: 'Menu2',
component: 'nested/menu2/index',
hidden: false,
alwaysShow: true,
meta: '{ "title": "menu2" }'
}
]
// 404路由
const notFoundRoutes = [
{
path: "/404",
component: () => import("@/views/404"),
hidden: true
},
]
const loadView = (view) => {
// 路由懒加载
// return (resolve) => require([`@/views/${view}`], resolve)
return () => import(`@/views/${view}`)
}
/**
* 格式化后端动态路由数据
* @param {{
* id:number,
* pid:number,
* path:string,
* name:string,
* component:string,
* hidden:boolean,
* alwaysShow:boolean,
* meta:string
* }[]} asyncRoutes
* @returns
*/
const formatAsyncRoutes = (asyncRoutes) => {
const menusMap = {}
// 将数组转换为键值对
asyncRoutes.forEach(item => {
menusMap[item.id] = item
})
const result = []
asyncRoutes.forEach(item => {
item.hidden = item.hidden ? true : false
item.alwaysShow = item.alwaysShow ? true : false
item.component && (item.component = loadView(item.component))
item.meta.length !== 0 && (item.meta = JSON.parse(item.meta))
let parent = menusMap[item.pid]
if (parent) {
// 下面reusult数组push进去对象实际是一次引用传递的过程,所以改变原对象可以影响到之后的数组
(parent.children || (parent.children = [])).push(item)
} else {
result.push(item)
}
})
return result
}
import { constantRouterMap } from "@/router"
const permission = {
state: {
routers: constantRouterMap,
addRouters: []
},
mutations: {
SET_ROUTERS: (state, routers) => {
state.addRouters = routers
state.routers = constantRouterMap.concat(routers)
}
},
actions: {
GenerateRoutes ({ commit }, data) {
return new Promise(resolve => {
//
// 将生成数组树结构的菜单并拼接404路由
const resultAsyncRoutes = formatAsyncRoutes(demoAsyncRoutes).concat(notFoundRoutes)
commit("SET_ROUTERS", resultAsyncRoutes)
//
resolve()
})
}
}
}
permission.js
import store from "./store";
import router from "./router";
router.beforeEach((to, from, next) => {
store.dispatch("GenerateRoutes").then(() => {
router.addRoutes(store.getters.addRouters);
next({ ...to, replace: true });
});
})