<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
</head>
<body>
<script>
// 判断当前的用户是否有该路由的权限
/*
routes.filter(route => route.meta.roles.includes(user.role))
roles 是用户的权限表
[] 可以有多种权限
route就是对应的路由配置中的路由对象
roles: ['a', 'b']
route.meta.roles: ['c']
roles会被循环两次,
第一次 role是 'a'
判断a是否在route.meta.roles中
第二次 role是 'b'
判断b是否在route.meta.roles中
最终some的结果为false
roles: ['a']
route.meta.roles: ['a', 'b']
a
roles: ['a']
route
*/
const routes = [
{
path: '/a',
meta: {
roles: ['a', 'b']
}
}, {
path: '/b',
children: [
{
path: 'a',
meta: {
roles: ['a']
}
}, {
path: 'b',
meta: {
roles: ['b']
}
}
]
}
]
function hasPermission(roles, route) {
if (route.meta && route.meta.roles) {
return roles.some(role => route.meta.roles.indexOf(role) >= 0)
} else {
return true
}
}
/**
* 递归过滤异步路由表,返回符合用户角色权限的路由表
* @param asyncRouterMap
* @param roles
*/
/*
asyncRouterMap 是一个路由配置数组
[
{
children: [
{}
]
}, {}, {}
]
*/
function filterAsyncRouter(asyncRouterMap, roles) {
const accessedRouters = asyncRouterMap.filter(route => {
if (hasPermission(roles, route)) {
if (route.children && route.children.length) {
route.children = filterAsyncRouter(route.children, roles)
}
return true
}
return false
})
return accessedRouters
}
console.log(filterAsyncRouter(routes, ['a']))
/* const routes = [
{
path: '/',
meta: {
role: ['admin', 'a', 'b']
},
children: [
{
path: 'a',
meta: {
role: ['admin', 'a']
}
}
]
}, {
path: '/edit',
meta: {
role: ['admin', 'b']
}
}
] */
/*
admin
/ /a /edit
a
/ /a
b
/ /edit
*/
function filterRole (arr) {
const newArr = arr.filter(route => {
if (route.meta.role.includes('b')) {
// 当当前路由有role属性时,判断当前路由是否有children子路由,如果有子路由,则继续判断子路由中是否有role
if (route.children && route.children.length) {
// 递归筛选有对应权限的路由
route.children = filterRole(route.children)
}
return true
}
})
return newArr
}
// console.log(newArr)
// const asyncRoutes = filterRole(routes)
// 最终调用router.addRoutes(asyncRoutes)
</script>
</body>
</html>