上周在做项目时,遇到一个需求,根据登录用户的权限,动态分配路由。只让他看到某些有权限的页面。捣鼓了半天,这里做一个总结。
动态路由方法
首先要知道添加动态路由需要使用到的方法 router.addRoutes, 其中routes 是代表符合路由数组,格式和常规的路由数组是一样的。
包含基本的 path,component 等参数。
// 参数必须是一个符合 routes 选项要求的数组。
router.addRoutes(routes: Array<RouteConfig>)
遇到的问题
在后台请求到此用户的路由权限列表后,我们需要把这个路由添加到路由列表中。但是后台传给我 component 属性是个字符串,并不是指向组件的对象。
最大的难点应该就是这里了。我们需要把当前的component 中的字符串解析成我们需要的组件对象。
我们可以这么去定义,如果我们解析到的路由列表是如下数组:
// 模拟请求到的数组
{
data: {
routerMap: [{
path: '/',
name: 'HelloWorld',
component: 'HelloWorld',
mate: {
name: '首页',
icon: 'el-icon-menu'
},
children: [{
path: 'menus-1',
component: 'Menus1',
mate: {
name: '菜单 1',
icon: 'el-icon-s-goods'
}
},
{
path: 'menus-2',
component: 'Menus2',
mate: {
name: '菜单 2',
icon: 'el-icon-user-solid'
}
}
]
}]
}
}
那么我们可以这么去做,先定义好 component ,然后再写一个方法,直接我们定义好的对象。
// routerMap.js
// 懒加载路由
const HelloWorld = () => import('@/components/HelloWorld')
const Menus1 = () => import('@/views/menus-1/Menus-1')
const Menus2 = () => import('@/views/menus-2/Menus-2')
// 查找路由,将字符串的component和对象的component对应起来
export const routerConfigMap = {
'HelloWorld': HelloWorld,
'Menus1': Menus1,
'Menus2': Menus2
}
接下里我们要将我们请求到的数组做一下处理和过滤
import {routerConfigMap} from '@/router/routerMap'
// 添加路由
addRouter () {
// ...请求到的路由 = routerMap
let routerList = this.filterRouter(routerMap)
this.$router.addRoutes(routerList)
}
// 过滤整理路由
filterRouter (routerMap) {
routerMap.forEach(item => {
item.component = routerConfigMap[item.component]
if (item.children) {
// 如果有子路由则继续这一步操作
return this.filterRouter(item.children)
}
})
return routerMap
}
这样就完成添加路由步骤。
核心代码已经列出,具体详情代码已经上传 GitHub。
如果需要根据权限进行过滤,那么在filterRouter函数中可以根据自己的需求进行处理。