elementui-admin实现动态路由
elementui-admin实现动态路由一:这里使用elementui-admin作为前端项目的架构 下载模板 并改造git地址:https://github.com/PanJiaChen/vue-admin-template下载下来之后就是改造成自己使用的这个是admin-template建议模板 功能不多,如果开发需要可以从https://github.com/PanJiaChen/vue-
elementui-admin实现动态路由
一:这里使用elementui-admin作为前端项目的架构 下载模板 并改造
git地址:https://github.com/PanJiaChen/vue-admin-template
下载下来之后就是改造成自己使用的 这个是admin-template建议模板 功能不多,如果开发需要可以从https://github.com/PanJiaChen/vue-element-admin 上面copy下来
下载好相关的依赖之后,按照自己的需要修改一些配置 比如
-
修改配置文件.env.development 后续生产环境 修改.env.production 即可
改成自己后台的接口
VUE_APP_BASE_API = 'http://127.0.0.1:8050/inv'
-
修改main.js
导入elementui 汉化包
import locale from 'element-ui/lib/locale/lang/zh-CN' // lang i18n
并把 mock测试数据 删除
-
修改部分 不多赘述 因为我是做后端的 前端的一些东西 说不明白
二:将后台的动态路由查出
我这里大致的思路就是 把路由分为两级,两种
一级就是目录菜单 比如系统管理和库存管理 二级就是目录下的菜单 账号管理,路由管理和角色管理
两种路由就是固定路由和动态路由 固定路由是写在前端,动态路由是存储在数据库中登录的时候根据账户绑定的角色 角色绑定的路由获取到的
后台用的是java 返回的数据结构是树形的json
把所有的路由查出来 父子路由之间 是根据id 绑定 的 这样我们就循环list 将id符合自己子路由的路由加入到自定义的集合中,然后过滤一级目录菜单即可,后端的任务就完成了
/*获取树形JSON*/
public List<Router> getJson(List<Router> routers) {
for (int i = 0; i < routers.size(); i++) {
int f = i;
List<Router> children = routers.stream()
.filter(router -> router.getParentId() == routers.get(f).getId())
.collect(Collectors.toList());
if (CollectionUtils.isEmpty(children)) {
continue;
}
routers.get(f).setUserRouters(children);
routers.get(f).setHasChildren(true);
}
return routers.stream().filter(router -> router.getRType() == Constants.Router.CONTENTS).collect(Collectors.toList());
}
返回到前端数据就长这样:
[
{
"createTime": "2021-08-25 10:01:09",
"updateTime": "2021-08-31 09:49:48",
"creator": "",
"updater": "USER-20210824-0001",
"deleteFlag": false,
"orgDeep": 1,
"id": 1,
"parentId": null,
"parentName": null,
"userRouters": [
{
"createTime": "2021-08-27 11:41:27",
"updateTime": "2021-08-31 14:34:05",
"creator": "",
"updater": "USER-20210824-0001",
"deleteFlag": false,
"orgDeep": 1,
"id": 5,
"parentId": 1,
"parentName": "系统管理",
"userRouters": null,
"hasChildren": false,
"rPath": "/user",
"rComponent": "/system/user",
"rRedirect": "",
"rTitle": "账号管理",
"rIcon": "el-icon-user",
"rType": 2,
"rName": "user",
"rSort": 1
},
{
"createTime": "2021-08-26 15:36:26",
"updateTime": "2021-08-31 14:17:32",
"creator": "",
"updater": "USER-20210824-0001",
"deleteFlag": false,
"orgDeep": 1,
"id": 2,
"parentId": 1,
"parentName": "系统管理",
"userRouters": null,
"hasChildren": false,
"rPath": "/routing",
"rComponent": "/system/routing",
"rRedirect": null,
"rTitle": "路由管理",
"rIcon": "el-icon-menu",
"rType": 2,
"rName": "routing",
"rSort": 2
},
{
"createTime": "2021-08-31 09:56:34",
"updateTime": "2021-08-31 14:34:05",
"creator": "USER-20210824-0001",
"updater": null,
"deleteFlag": false,
"orgDeep": 1,
"id": 7,
"parentId": 1,
"parentName": "系统管理",
"userRouters": null,
"hasChildren": false,
"rPath": "/role",
"rComponent": "/system/role",
"rRedirect": "",
"rTitle": "角色管理",
"rIcon": "el-icon-user-solid",
"rType": 2,
"rName": "role",
"rSort": 3
}
],
"hasChildren": true,
"rPath": "/system",
"rComponent": null,
"rRedirect": "/system",
"rTitle": "系统管理",
"rIcon": "el-icon-setting",
"rType": 1,
"rName": "system",
"rSort": 1
},
{
"createTime": "2021-08-27 11:42:51",
"updateTime": "2021-08-31 14:34:05",
"creator": "",
"updater": "USER-20210824-0001",
"deleteFlag": false,
"orgDeep": 1,
"id": 6,
"parentId": null,
"parentName": "",
"userRouters": null,
"hasChildren": false,
"rPath": "/sotck",
"rComponent": "",
"rRedirect": "/sotck",
"rTitle": "库存管理",
"rIcon": "el-icon-s-cooperation",
"rType": 1,
"rName": "stock",
"rSort": 2
}
]
三:前端拿到后台传过来的数据之后就要改造成路由所识别的路由数据 这话说着怎么那么别扭
我这里 刚开始搞了好久 用递归循环 加载路由 但是发现怎么样都不行,都怀疑人生了 也没找到原因,后面我先加载一级路由,然后二级路由用得递归,成功加载出,因为项目赶进度 我也没深入研究,所以就勉强用了 如果有兄弟实现了递归路由 麻烦贴下代码。谢谢了
下面是我动态加载的路由信息的方法 这里有个细节 就是component的路径需要用require才生效 如果没有加载出来路由大概就是没找到路由的地址
数据库中存的地址就是 vue文件的地址 比如 /system/routing 一级目录里的Layout 导入即可
import Layout from '@/layout'
export function recursionRouter(routerArray) {
/*后端json转换成路由*/
function routerFormat(routerList) {
let children = [];
let childRouter = {};
routerList.forEach(child => {
if(child.userRouters){ //菜单下如果还有子目录 则递归调用
childRouter = {
path: child.rPath,
name: child.rName,
component: resolve => require(['@/views' + child.rComponent], resolve),
meta: {title: child.rTitle, icon: child.rIcon},
alwaysShow:true,
children:routerFormat(child.userRouters)
}
}else{
childRouter = {
path: child.rPath,
name: child.rName,
component: resolve => require(['@/views' + child.rComponent], resolve),
meta: {title: child.rTitle, icon: child.rIcon}
}
}
children.push(childRouter);
})
return children;
}
let formatRouters = [];
routerArray.forEach(router => { //循环一级目录
let children;
if(router.userRouters){
children = routerFormat(router.userRouters);
}
let formatRouter = {
path: router.rPath,
name: router.rName,
component: Layout,
redirect: router.rRedirect,
meta: {title: router.rTitle, icon: router.rIcon},
alwaysShow: true,
children: children
};
formatRouters.push(formatRouter);
})
return formatRouters;
}
另外 ,我们动态加载出路由后使用 addRoutes 后 admin自带的面包屑会失效 原因是addRoutes 后的路由 并没有放入到 路由中
按java来说 我加载的值 没有给我追加到原来的对象上,所以他加载不出,
router.addRoutes(accessRoutes) //
我的解决方案是 用我自己的路由 ,我把动态路由和固定路由 放入到store中 让面包屑循环我的路由这样就没问题了
所以我在addRoutes 之前 把所有的路由放入到我自定义的store中
const routers = await store.dispatch('user/getInfo') //异步调用获取用户的可访问路由
const accessRoutes = await store.dispatch('permission/generateRoutes', routers)
router.addRoutes(accessRoutes)
然后改造下面包屑即可
基本上改到这里 就好了 这是我加入一些公共的模块 可以做一些简单权限管理系统
如果有需要 可以私聊我 我项目是私库没分享 ;
更多推荐
所有评论(0)