后端路由格式
[
{
path: "/user",
component: 'Layout',
alwaysShow: true,
name: 'UserModule',
meta: {title: "用户管理", icon: "el-icon-s-tools"},
children: [
{ path: "user",
component: "user/user/index",
name: "UserModuleUser",
meta: {title: "用户列表"}
},
{ path: "role",
component: "user/role/index",
name: "UserModuleRole",
meta: {title: "角色列表"}
},
{ path: "center",
component: "user/center/index",
name: "UserModuleCenter",
hidden: true,
meta: {title: "个人中心"}
}
]
}
];
src/store/permission.js
import { asyncRoutes,constantRoutes } from '@/router'
//constantRoutes 无权限控制页面
//asyncRoutes 权限控制页面
import { getInfo } from '@/api/user'
import Layout from '@/layout/index'
/**
* Use meta.role to determine if the current user has permission
* @param roles
* @param route
*/
function hasPermission(roles, route) {
if (route.meta && route.meta.roles) {
return roles.some(role => route.meta.roles.includes(role))
} else {
return true
}
}
/**
* Filter asynchronous routing tables by recursion//通过递归过滤异步路由表
* @param routes asyncRoutes
* @param roles
*/
export function filterAsyncRoutes(routes, roles) {
const res = []
routes.forEach(route => {
const tmp = {...route }//扩展运算符...
if (hasPermission(roles, tmp)) {
if (tmp.children) {
tmp.children = filterAsyncRoutes(tmp.children, roles)
}
res.push(tmp)
}
})
return res
}
const state = {
routes: [],
addRoutes: []
}
const mutations = {
SET_ROUTES: (state, routes) => {
state.addRoutes = routes
state.routes = constantRoutes.concat(routes)
}
}
const actions = {
generateRoutes({ commit }) {
return new Promise(resolve => {
// 向后端请求路由数据
getInfo().then(res => {
const accessedRoutes = filterAsyncRouter(res.data.menus)
accessedRoutes.push({path: '*', redirect: '/404', hidden: true})
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
})
})
}
}
//读取本地的菜单,测试环境可用。生产环境不行。
// const actions = {
// generateRoutes({ commit }, roles) {
// return new Promise(resolve => {
// let accessedRoutes
// if (roles.includes('admin')) {
// accessedRoutes = asyncRoutes || []
// } else {
// accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
// }
// commit('SET_ROUTES', accessedRoutes)
// resolve(accessedRoutes)
// })
// }
// }
// 遍历后台传来的路由字符串,转换为组件对象
export function filterAsyncRouter(asyncRouterMap) {
return asyncRouterMap.filter(route => {
if (route.component) {
// Layout组件特殊处理
if (route.component === 'Layout') {
route.component = Layout
} else {
route.component = loadView(route.component)
}
}
if (route.children != null && route.children.length != 0 && route.children && route.children.length) {
route.children = filterAsyncRouter(route.children)
}
return true
})
}
const loadView = (view) => require(`@/views/${view}`).default
export default {
namespaced: true,
state,
mutations,
actions
}
可能遇到的错误
1、Critical dependency: the request of a dependency is an expression
const loadView = (view) => require(`@/views/${view}`).default
结尾的.default 别忘记加。
const loadView= (view) => import(`@/views/${view}.vue`)
.vue 后缀别忘记加。
2、import 不识别变量,是依赖的版本问题,没找到解决办法。所以用require。
3、缺少依赖,不识别 require,用require项目运行卡住不动,用import运行正常。
const loadView = (view) => require(`@/views/${view}`).default
vue-loader at least v13.0.0+
npm install -D vue-loader vue-template-compiler