本人对前端不太熟悉,如果有不对的地方欢迎指出。
先放上我的菜单表结构:
CREATE TABLE `sys_menu` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`pid` int(11) NOT NULL COMMENT '父菜单ID',
`is_leaf` tinyint(4) NOT NULL COMMENT '0:不是叶子节点,1:是叶子节点',
`name` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '菜单名称',
`redirect` varchar(255) DEFAULT NULL COMMENT '跳转URL',
`url` varchar(64) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL COMMENT '路由地址',
`component` varchar(255) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '组件路径',
`perms` varchar(100) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '权限标识',
`icon` varchar(45) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL COMMENT '图标',
`icon_color` varchar(16) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT NULL,
`sort` tinyint(4) DEFAULT NULL COMMENT '排序',
`level` tinyint(4) NOT NULL COMMENT '菜单层级',
`status` tinyint(4) NOT NULL COMMENT '0:启用,1:禁用',
`remark` varchar(500) CHARACTER SET utf8 COLLATE utf8_general_ci DEFAULT '' COMMENT '备注',
PRIMARY KEY (`id`) USING BTREE
) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8 ROW_FORMAT=DYNAMIC COMMENT='系统菜单表';
然后经过后端代码处理之后返回到前端的结构是这样的:
{
"success": true,
"code": 20000,
"message": "成功",
"data": {
"menu_list": [
{
"id": 1,
"pid": 0,
"isLeaf": 0,
"name": "系统设置",
"url": "/admin/system",
"redirect": "/bbsacl/sysmenu",
"component": "form/index",
"perms": "bbs:bbsacl:sysmenu:list",
"icon": "form",
"iconColor": null,
"sort": 0,
"level": 1,
"status": 0,
"remark": "系统设置",
"children": []
},
{
"id": 2,
"pid": 0,
"isLeaf": 0,
"name": "权限管理",
"url": "/admin/auth/sys_role",
"redirect": "/bbsacl/sysrole",
"component": "form/index",
"perms": "bbs:bbsacl:sysrole:list",
"icon": "form",
"iconColor": null,
"sort": 0,
"level": 1,
"status": 0,
"remark": "权限管理",
"children": [
{
"id": 6,
"pid": 2,
"isLeaf": 1,
"name": "角色管理",
"url": "/admin/auth/sys_role/list",
"redirect": "/admin/role/index",
"component": "role/index",
"perms": "bbs:bbsacl:sysrole:list",
"icon": "form",
"iconColor": "",
"sort": 0,
"level": 1,
"status": 0,
"remark": "角色管理",
"children": []
}
]
}
]
}
}
1、首先在store/modules/user.js 文件里的getinfo方法里将后端返回的菜单先存到vuex里
我这里取data.menu是因为后面修改的时候把菜单数据放在menu这个字段里返回了,相当于上面的menu_list改成了menu。
之后要去store/getters.js 里添加一行代码:
2、然后在router目录下创建这两个文件
内容分别是:
- _import_development.js:module.exports = file => require('@/views/' + file + '.vue').default // vue-loader at least v13.0.0+
- _import_production.js:module.exports = file => () => import('@/views/' + file + '.vue')
3、然后在utils目录下新建一个menu.js文件,将下面内容放进去
import Layout from '@/layout'
const _import = require('../router/_import_' + process.env.NODE_ENV) // 获取组件的方法
export default {
//过滤菜单数组,作用是处理每一个菜单的component组件的引入
filterAsyncRouter(routes) {
const res = []
routes.forEach(route => {
const tmp = { ...route }
if (tmp.component) {
if (tmp.component === 'Layout') {
tmp.component = Layout
} else {
//因为有的菜单的组件项到了这里会变成对象而不是字符串,所以进行一下判断
if (typeof (tmp.component) == 'string') {
tmp.component = _import(tmp.component)
} else {
tmp.component = tmp.component
}
}
}
if (tmp.children && tmp.children.length > 0) {
tmp.children = this.filterAsyncRouter(tmp.children)
}
res.push(tmp)
})
return res
},
//这里按照vue的路由格式生成路由内容
generateRoutes(menus, flag = false) {
const routes = []
menus.forEach(menu => {
const route = {
path: menu.url,
component: 'Layout',
redirect: menu.redirect,
name: menu.name,
children: [],
meta: {
title: menu.name,
icon: menu.icon
}
}
if (flag) {
route.component = menu.component;
}
if (menu.children && menu.children.length > 0) {
route.children = this.generateRoutes(menu.children, true)
} else {
route.path = menu.redirect
route.children = [
{
path: menu.url,
component: menu.component,
meta: { title: menu.name, icon: menu.icon }
},
];
}
routes.push(route)
})
return this.filterAsyncRouter(routes)
}
}
4、然后去到src目录下的permission.js文件里,引入这两个文件:
然后在下面的代码里先通过getinfo方法获取到菜单数据(其实也可以通过store.getter.menu获取),然后将菜单数据放进menu.js 文件里的generateRoutes方法得到组装好的路由,最后再将组装好的留有添加到router中,即可完成动态路由的添加
- 补充: menu.js 这个文件里的filterAsyncRouter方法是对后端返回的菜单数据的component组件引入, generateRoutes方法则是按照vue-router的格式组装路由并返回。
大致流程就是这样,如果有不明白的朋友欢迎留言提问,知无不言。