- 前端手动配置静态路由constantRouterMap与动态路由池asyncRouterMap,并给动态路由池配置所需权限
// 静态路由
export const constantRouterMap = [
{ path: '/login', component: () => import('@/views/login/index'), hidden: true },
{
path: '/',
component: Layout,
name: 'system',
hidden: true,
meta: { title: '首页' },
children: [{
path: '',
name: 'Home',
component: () => import('@/views/index'),
meta: { title: '首页', icon: 'example' }
}]
},
{ path: '/401', component: () => import('@/views/401'), hidden: true },
{ path: '/404', component: () => import('@/views/404'), hidden: true }
]
export const asyncRouterMap = [
{
path: '/auth',
component: Layout,
redirect: '/auth/organ',
name: 'Authoritys',
meta: { title: '权限管理', icon: 'user-cog'},
children: [
{
path: 'organ',
name: 'Organ',
component: () => import('@/views/organ'),
meta: { title: '机构管理', icon: 'users', privilegs: ['organ'] }
},
{
path: 'role',
name: 'Roles',
component: () => import('@/views/role'),
meta: { title: '角色管理', icon: 'address-book', privilegs: ['role'] }
},
{
path: 'user',
name: 'Users',
component: () => import('@/views/user'),
meta: { title: '用户管理', icon: 'user', privilegs: ['user'] }
}
]
}
{ path: '*', redirect: '/404', hidden: true }
]
注意事项:这里有一个需要非常注意的地方就是 404 页面一定要最后加载,如果放在constantRouterMap一同声明了404,后面的所以页面都会被拦截到404,详细的问题见addRoutes when you've got a wildcard route for 404s does not work
2. 接口获取用户权限数组
通过parentId递归整理结构 用VUEX与localstage存下
权限数组第一层决定页面或者某些模块的显示, 子集决定功能的操作显示
auth = [{
name: '首页',
id: 1,
child: [{
name: '导出功能',
id: 11
}, {
name: '导入功能',
id: 12
}]
}, {
name: '学生',
id: 2,
child: [{
name: '增加',
id: 21
}, {
name: '删除',
id: 22
}]
}]
- 3.1 登录成功 根据接口返回权限数据 生成可访问路由
3.2 页面刷新时, 根据localstage的权限 重新生成可访问路由
3.3 若有切换角色功能时, 根据切换的角色的权限 重新生成路由
- 具体页面元素通过VUEX获取权限数组进行显示/隐藏操作
- 需要修改的主要是判断权限的业务代码部分
动态路由实现
- 前端路由生成由2部分组成,静态路由与动态生成路由.
静态路由constantRouterMap由401,404,登录页等不需要权限页面组成.
动态生成路由从路由池asyncRouterMap中,通过权限匹配筛选过滤组成.
路由池asyncRouterMap配置如下, 在meta对象加入所需的权限数组privilegs.
使没有权限的用户无法手敲地址进入无权限的路由, 若手敲则直接进入401提示页面
export const asyncRouterMap = [
{
path: '/auth',
component: Layout,
redirect: '/auth/organ',
name: 'Authoritys',
meta: { title: '权限管理', icon: 'user-cog'},
children: [
{
path: 'organ',
name: 'Organ',
component: () => import('@/views/authority/organ/index'),
meta: { title: '机构管理', icon: 'users', privilegs: ['organ'] }
},
{
path: 'role',
name: 'Roles',
component: () => import('@/views/authority/role/index'),
meta: { title: '角色管理', icon: 'address-book', privilegs: ['role'] }
},
{
path: 'user',
name: 'Users',
component: () => import('@/views/authority/user/index'),
meta: { title: '用户管理', icon: 'user', privilegs: ['user'] }
}
]
}
]
- 生成动态路通过VUEX的action实现, 每次需要生成路由是调用GenerateRoutes传入privilegs实现
// 判断是否与当前用户权限匹配
function hasPermission(privilegs, route) {
if (route.meta && route.meta.privilegs) {
return privilegs.some(privileg => {
// 判断是否符合权限的业务代码
})
} else {
return true
}
}
// 递归过滤异步路由表,返回符合用户所有权限的路由表
function filterRouter(routes, privilegs, isChild) {
const res = []
routes.map(route => {
const tmp = { ...route }
if (hasPermission(privilegs, tmp)) {
if (tmp.children) {
tmp.children = filterRouter(tmp.children, privilegs, 1)
}
res.push(tmp)
}
})
return res
}
actions: {
GenerateRoutes({ commit }, data) {
return new Promise(resolve => {
const privilegs = data.privilegs.split(',')
const accessedRouters = filterRouter(asyncRouterMap, privilegs, 0)
// 存下生成的路由
commit('SET_ROUTERS', accessedRouters)
resolve()
})
}
}
调用:
// 传入用户的权限
store.dispatch('GenerateRoutes', { privilegs }).then(() => {
router.onReady(() => {
// store.getters.addRouters即为生成的匹配权限的路由
router.addRoutes(store.getters.addRouters)
})
})
- 配置permission.js, 判断路由切换时的是否有权限, 并做相应处理
// 判断是否有权限进入页面 permissions用户的权限数组
function hasPermission(permissions, privileg) {
if (!privileg) return true
return permissions.some(permission => permission.indexOf(privileg) >= 0)
}
const whiteList = ['/login'] // 不重定向白名单
router.beforeEach((to, from, next) => {
NProgress.start()
if (getToken()) {
if (to.path === '/login') {
next()
NProgress.done()
} else {
// 若刷新重新读取Cookies的权限数据 生成路由
if (store.getters.privilegs.length === 0) {
const privilegs = getCookies('privilegs')
// 根据权限生成可访问的路由表
store.dispatch('GenerateRoutes', { privilegs }).then(() => {
router.onReady(() => {
router.addRoutes(store.getters.addRouters)
})
next()
})
} else {
// 判断是否有权限进入页面
if (hasPermission(store.getters.privilegs, to.meta.privilegs)) {
next()
} else {
next({ path: '/401', replace: true, query: { noGoBack: true }})
}
}
}
} else {
if (whiteList.indexOf(to.path) !== -1) {
next()
} else {
next('/login')
}
}
})