无界AI教程项目--动态路由配置(六)

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档

目录

前言

一、数据准备

1、数据库

二、使用步骤

1、添加查询路由表的方法

2、路由配置

总结


前言

本项目是将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提供了大量能使我们快速便捷地处理数据的函数和方法。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值