首先看到一些大师在前后端路由权限交互中一般后端给返回一个可访问的带pid一维路由数组,pid代表父级id,这个数组要前端格式化成树形结构路由。此方式稍显麻烦,为什么不把可访问的路由name数据发给前端?例如vue端建有一个完整路由表,根据name数组就可过滤出一个可访问的路由结构,而不必指定它的父级id。其实在路由守卫里判断当前路由name是否在允许的name集合里控制路由权限也可行。
一、先实现带pid的路由数组的格式化方法:
1.后台数据格式化成树
let formatTree = (data) => { //data是后端路由的数据
let ps = data.filter(d => d.pid == 0)
const cs = data.filter(d => d.pid != 0)
let format = (ps) => {
ps.forEach(p => {
cs.forEach(c => {
if (p.id == c.pid) {
if (p.children) p.children.push(c)
else p.children = [c]
}
})
p.children && format(p.children)
})
return ps
}
return format(ps)
}
2.树形结构格式化路由
formatRoutes(data) { //data是上边的树形结构数据
let routes = [];
data.length &&
data.forEach(route => {
let r = { //格式化成需要的结构
name: route.title,
component: route.component,
};
if (route.children) {
r.child = this.formatRoutes(route.children);
}
routes.push(r);
});
return routes;
}
二、直接发给前端可访问路由name的情况:
不用担心只给子路由name而无法得到父级路由形成树形结构,注意递归的妙用,上面也是递归。
function selectArrayByNames(arr,names) { //arr是vue完整路由表,names是后端给的路由name集合
let _arr = [];
arr.forEach((r) => {
if (names.indexOf(r.name) != -1) {
_arr.push(r);
return //不必判断有没有children了,匹配names的路由都是最底层的路由。
}
if (r.children) {
r.children = this.selectArrayByNames(r.children,names);
if (r.children.length > 0) _arr.push(r);
}
});
return _arr
}