步骤1:登录后后端接口返回 如下结构数据:
{
"data":[
{"funcId":2,"funcName":"应用管理","parentId":1,"path":"/appBusinessManage","iconUrl":"d","sortId":1,"funcLevel":2,"children":[{"funcId":7,"funcName":"应用管理","parentId":2,"path":"/appBusinessManage/index","iconUrl":"a","sortId":1,"funcLevel":3,"children":null}]},
{"funcId":3,"funcName":"角色管理","parentId":1,"path":"/roleManagement","iconUrl":"f","sortId":2,"funcLevel":2,"children":[{"funcId":9,"funcName":"功能角色","parentId":3,"path":"/roleManagement/index","iconUrl":"a","sortId":1,"funcLevel":3,"children":null}]},
{"funcId":11,"funcName":"用户管理","parentId":1,"path":"/userManage","iconUrl":"a","sortId":3,"funcLevel":2,"children":[{"funcId":26,"funcName":"用户管理","parentId":11,"path":"/admin/listUser","iconUrl":null,"sortId":11,"funcLevel":3,"children":null}]},
{"funcId":24,"funcName":"科室管理","parentId":1,"path":"/departmentManage","iconUrl":null,"sortId":4,"funcLevel":2,"children":[{"funcId":25,"funcName":"科室管理","parentId":24,"path":"/departmentManage/index","iconUrl":null,"sortId":1,"funcLevel":3,"children":null}]}
],
"retCode":0
}
步骤2:将返回路由保存在store中 进行如下操作
saveAsyncRoutes(filterRoutes) {
const routes = getAsyncRoute(filterRoutes);
router.addRoutes(routes);
setStorage("asyncRoutes", filterRoutes);
}
步骤3:路由文件前端写死内容
import Layout from "@/components/Layout";
const routerMap = [
{
path: "/dashboardManage",
component: Layout,
redirect: "/dashboard/index",
meta: {
title: "首页",
icon: "desktop",
name: "/dashboardManage"
},
children: [
{
path: "/dashboard/index",
component: () => import("@/views/dashboard/index.vue"),
meta: {
title: "首页",
name: "/dashboard/index",
hidden: true
}
}
]
},
{
path: "/appBusinessManage",
component: Layout,
meta: {
title: "应用管理",
icon: "appstore",
name: "/appBusinessManage"
},
redirect: "/appBusinessManage/index",
children: [
{
path: "/appBusinessManage/index",
component: () => import("@/views/appBusinessManage"),
meta: {
title: "应用管理",
name: "/appBusinessManage/index"
}
},
]
},
{
path: "/roleManagement",
component: Layout,
meta: {
title: "角色管理",
icon: "contacts",
name: "/roleManagement"
},
redirect: "/roleManagement/index",
children: [
{
path: "/roleManagement/index",
component: () => import("@/views/roleManagement"),
meta: {
title: "功能角色",
name: "/roleManagement/index"
}
},
{
path: "/roleApplication/index",
component: () => import("@/views/roleApplication"),
meta: {
title: "应用角色",
name: "/roleApplication/index"
}
}
]
},
]
export default routerMap;
步骤4:数据处理,getAsyncRoute 在下面文件中进行处理,ValidationRole为一个配置开关,如果返回true,代表启动动态路由,如果返回false,直接走前端写死路由即可
import routerMaps from '@/router/router.map';
import router2Map from '@/router/appRouter.ts';
import { ValidationRole } from '@/config';
import { MenuStore } from '../store/menu';
/**
* @param roleRoutes 权限路由集合
* @param routerMap 待挂载的路由集合
* @param children 树节点
* @param key 唯一key
* @returns 通过权限过滤后的路由
*/
// 系统管理路由
export function getAsyncRoute(roleRoutes, routerMap = routerMaps, children = 'children', key = 'path') {
// 不需要权限验证时 直接返回完整路由
if (!ValidationRole) {
return routerMaps;
}
// 传来的权限路由不存在 则返回空[]
if (!roleRoutes) {
return [];
}
try {
roleRoutes = JSON.parse(roleRoutes);
} catch (error) { }
// 对数组进行降维打击,将子路由children和父路由都放到一个维度的数组里面
const afterSqueeze = squeeze(roleRoutes, children);
console.log("afterSqueeze",afterSqueeze)
// 所有权限路由path集合
const pathList = afterSqueeze.map(r => r[key]);
console.log("pathList",pathList)
// 过滤权限路由
console.log("routerMap",routerMap)
const asyncRoute = filterRouter(routerMap, key);
console.log("asyncRoute",asyncRoute)
// 递归排序
sortRoute(asyncRoute)
return asyncRoute;
/**
* @default key =>'path'
* @param key 服务端传来的路由的路径 通过此字段进行过滤
* @param routes 待挂载的路由集合
* @returns 过滤后的路由集合
*/
前端写死的路由 根据 pathList 服务端返回的路由进行过滤,最终得到即将渲染的路由。
function filterRouter(routes, key = 'path') {
return routes.filter(r => {
if (pathList.includes(r.path)) {
const meta = afterSqueeze.find((j) => j[key] === r.path);
r.meta = { ...r.meta, ...meta };
r.children && (r.children = filterRouter(r.children));
return true;
}
});
}
/**
*
* @param routes 待排序的路由集合
* 根据meta.sortOrder由小到大排序
*/
function sortRoute(routes) {
routes.sort((a, b) => {
// tslint:disable: no-unused-expression
a.children && sortRoute(a.children);
b.children && sortRoute(b.children);
// return a.meta.sortOrder - b.meta.sortOrder
return 1;
});
}
}
/**
* 数组降维
* @param arr 待降维的数组
* @param key 需要降维的字段
* @returns 降维后的一维数组
*/
export function squeeze(arr, key = 'children') {
const newArr = [];
function fn(v) {
v.map(r => {
newArr.push(r);
if (r[key]) {
fn(r[key]);
}
});
}
fn(arr);
return newArr;
}
//# sourceMappingURL=permission.js.map
步骤5:渲染导航
menuItem(r) {
let key = "";
if (r.children && r.children.length > 0) {
key = r.children[0].path;
}
else {
key = r.path;
}
return (<a-menu-item key={key}>
{r.meta.icon && (<a-icon type={r.meta.icon} style="font-size:16px" />)}
<span class="padding-left">{r.meta.title}</span>
</a-menu-item>);
}
subItem(r) {
return (<a-sub-menu key={r.path} onTitleClick={this.titleClick} title={[
<a-icon type={r.meta.icon} style="font-size:16px" />,
<span class="padding-left" v-text={r.meta.title} />
]}>
{r.children.map(i => this.menuItem(i))}
</a-sub-menu>);
}
render() {
return (
<a-layout-sider collapsible trigger={null} v-model={this.$props.collapsed} width={256}>
<a-menu onClick={this.menuClick} selectedKeys=
{[this.$route.path]} openKeys={this.openkeys} mode="inline"
theme="light" style="height: 100%; ">
<a-menu-item key="/dashboard/index">
<a-icon type="desktop" style="font-size:16px" />
<span class="padding-left">首页</span>
</a-menu-item>
{this.routerMaps.map((r) => r.children.length > 1
? this.subItem(r)
: this.menuItem(r))
}
</a-menu>
</a-layout-sider>);
}
常见问题FAQ
- 免费下载或者VIP会员专享资源能否直接商用?
- 本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
- 提示下载完但解压或打开不了?
- 找不到素材资源介绍文章里的示例图片?
- 模板不会安装或需要功能定制以及二次开发?
发表评论
还没有评论,快来抢沙发吧!