提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
目录
前言
本项目是将vue-element-admin的路由为基础,改造为动态路由。
一、数据准备
1、数据库
(1)创表
根据路由存在的属性、父子相关联关系创建路由表,路由属性暂时用到这些,后面还可以添加,建议再加上创建时间、最后更新时间、创建人、最后更新人字段
CREATE TABLE `t_table_menu_routers` (
`ID` int NOT NULL AUTO_INCREMENT COMMENT '路由ID',
`PARENT_ID` int DEFAULT NULL COMMENT '父项ID',
`ROUTER_PROJECT` varchar(100) NOT NULL COMMENT '所属项目',
`ROUTER_PATH` varchar(100) NOT NULL DEFAULT '/' COMMENT '路由路径',
`ROUTER_REDIRECT` varchar(100) DEFAULT NULL COMMENT '路由重定向',
`ROUTER_COMPONENT` varchar(200) DEFAULT NULL COMMENT '路由引用组件路径',
`ROUTER_HIDDEN` tinyint(1) DEFAULT '1' COMMENT '路由是否显示,1 显示, 0 隐藏',
`ROUTER_NAME` varchar(100) DEFAULT NULL COMMENT '路由名称',
`ROUTER_TITLE` varchar(100) DEFAULT NULL COMMENT '路由标题',
`ROUTER_ICON` varchar(100) DEFAULT NULL COMMENT '路由图标名称',
`ROUTER_KEEPALIVE` tinyint(1) DEFAULT '1' COMMENT '是否缓存',
`ROUTER_AFFIX` tinyint(1) DEFAULT '1' COMMENT '',
`ROUTER_NOCACHE` tinyint(1) DEFAULT '1' COMMENT '不被keep-alive缓存,1 不被缓存, 0 被缓存',
`ROUTER_ALWAYSSHOW` tinyint(1) DEFAULT '1' COMMENT '',
`ROUTER_ROLES` varchar(100) DEFAULT NULL COMMENT '角色',
`ROUTER_ACTIVE_MENU` varchar(100) DEFAULT NULL COMMENT '路由角色',
PRIMARY KEY (`ID`)
) ENGINE=InnoDB AUTO_INCREMENT=21 DEFAULT CHARSET=utf8mb3;
(2)准备数据
INSERT INTO `t_table_menu_routers` VALUES
(100,0,"wujie","/redirect","","Layout",1,"","","",null,0,0,0,"",""),
(100100,100,"wujie","/redirect/:path(.*)","","@/views/redirect/index",0,"","","",null,0,0,0,"",""),
(101,0,"wujie","/login","","@/views/login/index",1,"","","",null,0,0,0,"",""),
(102,0,"wujie","/auth-redirect","","@/views/login/auth-redirect",1,"","","",null,0,0,0,"",""),
(103,0,"wujie","/404","","@/views/error-page/404",1,"","","",null,0,0,0,"",""),
(104,0,"wujie","/401","","@/views/error-page/401",1,"","","",null,0,0,0,"",""),
(105,0,"wujie","/","/dashboard","Layout",0,"","","",null,0,0,0,"",""),
(105100,105,"wujie","dashboard","","@/views/dashboard/index",0,"管理2","管理","dashboard",null,1,1,0,"",""),
(106,0,"wujie","/documentation","","Layout",0,"","","",null,0,0,0,"",""),
(106100,106,"wujie","index","","@/views/documentation/index",0,"Documentation","Documentation","documentation",null,1,1,0,"",""),
(107,0,"wujie","/guide","/guide/index","Layout",0,"","","",null,0,0,0,"",""),
(107100,107,"wujie","index","","@/views/guide/index",0,"Guide","Guide","guide",null,0,1,0,"",""),
(108,0,"wujie","/profile","/profile/index","Layout",1,"","","",null,0,0,0,"",""),
(108100,108,"wujie","index","","@/views/profile/index",0,"Profile","Profile","user",null,0,1,0,"",""),
(109,0,"wujie","/permission","/permission/page","Layout",0,"Permission","Permission","lock",null,0,0,1,"admin,editor",""),
(109100,109,"wujie","page","","@/views/permission/page",0,"PagePermission","Page Permission","",null,0,0,0,"admin",""),
(109101,109,"wujie","directive","","@/views/permission/directive",0,"DirectivePermission","Directive Permission","",null,0,0,0,"",""),
(109102,109,"wujie","role","","@/views/permission/role",0,"RolePermission","Role Permission","",null,0,0,0,"admin",""),
(110,0,"wujie","/example","/example/list","Layout",0,"Example","Example","el-icon-s-help",null,0,0,0,"",""),
(110100,110,"wujie","create","","@/views/example/create",0,"CreateArticle","Create Article","edit",null,0,0,0,"","");
注意:数据可能存在问题,功能测试时仅用到其中一条,大伙使用时最好自己重新处理。
二、使用步骤
1、添加查询路由表的方法
(1)在server/api/menu.js中加如获取路由数据的服务 getRouters
exports.getRouters = (req, res) => {
let query = req.query
var sql = 'select * from mysql_database_fir.t_table_menu_routers;'
db.query(sql, (err, data) => {
if(err) {
return res.send('错误:' + err.message)
}
res.send(data)
})
}
(2)在server/index.js中添加配置 getRouters
router.get('/getRouters', menu.getRouters)
2、路由配置
(1)注释掉原有的路由
在router/index.js中,constantRoutes 是默认不变的,所有用户都会用到,可以不动;asyncRoutes 是会按权限处理的,此处注释掉,通过服务获取数据
(2)路由数据查询
在store/modules/permission.js中添加查询服务,找到actions中的generateRoutes函数,默认accessedRoutes获取的是上面默认配置的asyncRoutes数据,此处改为通过服务获取
let accessedRoutes
const routers = Vue.prototype.$apiGet('/getRouters', {}).then(res=>{
return routesPackaging(res)
})
routers.then((result)=>{
if (roles.includes('admin')) {
accessedRoutes = result || []
} else {
accessedRoutes = filterAsyncRoutes(result, roles)
}
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
})
注意:
① 服务调用使用 Vue.prototype.$apiGet 方式,与.vue文件中调用方式不同
② 不能直接使用查询结果,因为得到的数据时promise类型,需要处理一下,使用最后的result
routers.then((result)=>{
console.log(result)
})
② generateRoutes函数中使用了routesPackaging自定义方法,主要是用来把服务返回的数据组装成路由格式,具体代码如下
// 路由外层属性
const routeMap = {
ID: 'id',
PARENT_ID: 'parentId',
ROUTER_PATH: 'path',
ROUTER_REDIRECT: 'redirect',
ROUTER_COMPONENT: 'component',
ROUTER_HIDDEN: 'hidden',
ROUTER_NAME: 'name',
ROUTER_ALWAYSSHOW: 'alwaysShow',
ROUTER_BREAD_MENU: 'breadcrumb'
}
// 路由meta属性
const routeMeta = {
ROUTER_TITLE: 'title',
ROUTER_ICON: 'icon',
ROUTER_AFFIX: 'affix',
ROUTER_NOCACHE: 'noCache',
ROUTER_ROLES: 'roles',
ROUTER_ACTIVE_MENU: 'activeMenu',
ROUTER_KEEPALIVE: 'keepAlive',
}
// 值为boolean类型的属性:mysql中boolean类型数据一般用1、0代替,此处需要识别转换
const routeBool = ['hidden', 'affix', 'noCache', 'alwaysShow']
// 路由组装
export const routesPackaging = function (dataList) {
function relationsProcess(parents, dataList) {
let datas = []
for (let i = 0; i < parents.length; i++) {
for (let j = 0; j < dataList.length; j++) {
if (parents[i].id === dataList[j].parentId) {
if (parents[i].children) {
parents[i].children.push(dataList[j])
} else {
parents[i].children = [dataList[j]]
}
}
}
if (emptyCheck(parents[i].children)) {
relationsProcess(parents[i].children, dataList)
}
}
}
let parents = []
for (let i = 0; i < dataList.length; i++) {
dataList[i] = routeAssemble(dataList[i])
if (dataList[i].parentId === 0) {
parents.push(dataList[i])
}
}
relationsProcess(parents, dataList)
return parents
}
// 路由组装--不同类型的属性区分
const routeAssemble = function (data) {
let route = {
meta: {}
}
for (let key in routeMap) {
if (emptyCheck(data[key])) {
if (routeMap[key] === 'component') {
if (data[key] === 'Layout') {
route[routeMap[key]] = Layout
} else {
route[routeMap[key]] = loadView(data[key])
}
} else if (routeBool.includes(routeMap[key])) {
if (data[key] === 1) {
route[routeMap[key]] = true
}
} else {
route[routeMap[key]] = data[key]
}
}
}
for (let key in routeMeta) {
if (emptyCheck(data[key])) {
if (routeBool.includes(routeMeta[key])) {
if (data[key] === 1) {
route.meta[routeMeta[key]] = true
}
} else {
if (routeMeta[key] === 'roles') {
route.meta[routeMeta[key]] = data[key].split(',')
} else {
route.meta[routeMeta[key]] = data[key]
}
}
}
}
return route
}
// 路由组装--component属性处理
// 注意,require中的路径需要拼装,不能直接使用完整的路径,否者无法识别
export const loadView = (view) => {
return (resolve) => require([`@/views${view}`], resolve)
}
(3)数据使用
在业务界面使用
let data = this.$store.state.permission.addRoutes
总结
提示:这里对文章进行总结:
例如:以上就是今天要讲的内容,本文仅仅简单介绍了pandas的使用,而pandas提供了大量能使我们快速便捷地处理数据的函数和方法。