Vue-element-admin实现动态路由
一 克隆与安装Vue
此步骤省略,因为都是对Vue-element-admin进行二次开发
二 关于Vue-element-admin内部结构分析
1 静态路由
vue-element-admin是一款开源免费前端后台系统管理框架,clone即用,非常方便,对应它存在的两种路由设计,一种是静态路由,一种是动态路由。
这是vue为了提供的静态路由中一些常用页面,比如根目录,登录,404等,如果还需要添加左边栏菜单,可以模仿静态路由的设计里面,还有权限的设计。
2 动态路由
(1)修改/src/store/modules/permission.js 文件
import { asyncRoutes, constantRoutes } from '@/router'
import { getAuthMenu } from '@/api/user'
import Layout from '@/layout'
/**
* Use meta.role to determine if the current user has permission
* @param roles
* @param route
*/
function hasPermission(roles, route) {
if (route.meta && route.meta.roles) {
return roles.some(role => route.meta.roles.includes(role))
} else {
return true
}
}
/**
* 后台查询的菜单数据拼装成路由格式的数据
* @param routes (resolve: any) => require([`@/views/${view}.vue`], resolve)
*/
export function generaMenu(routes, data) {
data.forEach(item => {
// alert(JSON.stringify(item))
const menu = {
path: item.path === '#' ? item.id + '_key' : item.path,
// component: item.component === '#' ? Layout : () => import(`@/views${item.component}`),
component: item.component === '#' ? Layout : (resolve) => require([`@/views${item.component}`], resolve),
hidden: item.hidden,
redirect: item.redirect,
children: [],
name: item.name,
meta: item.meta
// meta: { title: item.name, id: item.id, roles: ['admin'] }
}
if (item.children) {
generaMenu(menu.children, item.children)
}
routes.push(menu)
})
}
/**
* Filter asynchronous routing tables by recursion
* @param routes asyncRoutes
* @param roles
*/
export function filterAsyncRoutes(routes, roles) {
const res = []
routes.forEach(route => {
const tmp = { ...route }
if (hasPermission(roles, tmp)) {
if (tmp.children) {
tmp.children = filterAsyncRoutes(tmp.children, roles)
}
res.push(tmp)
}
})
return res
}
const state = {
routes: [],
addRoutes: []
}
const mutations = {
SET_ROUTES: (state, routes) => {
state.addRoutes = routes
state.routes = constantRoutes.concat(routes)
}
}
const actions = {
generateRoutes({ commit }, roles) {
return new Promise(resolve => {
const loadMenuData = []
// 先查询后台并返回左侧菜单数据并把数据添加到路由
getAuthMenu(state.token).then(response => {
let data = response
if (response.code !== 20000) {
alert(JSON.stringify('菜单数据加载异常'))
// throw new Error('菜单数据加载异常')
} else {
data = response.data
Object.assign(loadMenuData, data)
const tempAsyncRoutes = Object.assign([], asyncRoutes)
// tempAsyncRoutes = asyncRoutes
generaMenu(tempAsyncRoutes, loadMenuData)
let accessedRoutes
if (roles.includes('admin')) {
// alert(JSON.stringify(asyncRoutes))
accessedRoutes = tempAsyncRoutes || []
} else {
accessedRoutes = filterAsyncRoutes(tempAsyncRoutes, roles)
}
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
}
// generaMenu(asyncRoutes, data)
}).catch(error => {
console.log(error)
})
})
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
对照一下原版就可以发现更改的部分,这里面一般在编译的时候会出现rang of null的错误,这是因为你的babel-eslint版本过高的原因,因为老外改过打包的底层逻辑。所以我门一劳永逸,直接降低版本:
npm i @7.2.3" target="_blank">babel-eslint@7.2.3
* 修改 /src/router/index.js *
export const asyncRoutes = [
{ path: '*', redirect: '/404', hidden: true }
]动态路由只留下这个就行了。不过你之前写过的静态路径也要注释掉。
(3) 添加动态路由的请求方法 /src/api/user.js
export function getAuthMenu() {
return request({
url: '/configinfo/getAuthMenu ',
method: 'post'
})
}这里面你需要什么参数可以携带进去,比如权限什么都可能。
(4) 重点就是后端返回的JSON串了
{"code":20000,"data":[{"id":1,"hidden":true,"name":"GSMSystem","path":"/GSMSystem","pid":0,"url":"/GSMSystem","alwaysShow":true,"component":"#","meta":{"icon":"icon","status":true,"title":"GSM后台"},"children":[{"alwaysShow":true,"component":"/GSMSystem/paramOption/index","hidden":false,"id":11,"meta":{"icon":"paramOption","status":true,"title":"参数配置"},"name":"paramOption","path":"GSMSystem/paramOption","pid":30,"url":"GSMSystem/paramOption"},{"alwaysShow":true,"component":"/GSMSystem/logInformation/index","hidden":false,"id":11,"meta":{"icon":"logInformation","status":true,"title":"日志显示"},"name":"logInformation","path":"GSMSystem/logInformation","pid":30,"url":"GSMSystem/logInformation"},{"alwaysShow":true,"component":"/GSMSystem/logInformationQuery/index","hidden":false,"id":11,"meta":{"icon":"logInformationQuery","status":true,"title":"日志查询"},"name":"logInformationQuery","path":"GSMSystem/logInformationQuery","pid":30,"url":"GSMSystem/logInformationQuery"},{"alwaysShow":true,"component":"/GSMSystem/scanRateStatus/index","hidden":false,"id":11,"meta":{"icon":"scanRateStatus","status":true,"title":"扫描状态"},"name":"scanRateStatus","path":"GSMSystem/scanRateStatus","pid":30,"url":"GSMSystem/scanRateStatus"},{"alwaysShow":true,"component":"/GSMSystem/heartLog/index","hidden":false,"id":11,"meta":{"icon":"heartLog","status":true,"title":"GSM心跳显示"},"name":"heartLog","path":"GSMSystem/heartLog","pid":30,"url":"GSMSystem/heartLog"},{"alwaysShow":true,"component":"/GSMSystem/updateData/index","hidden":false,"id":11,"meta":{"icon":"updateData","status":true,"title":"更新程序"},"name":"updateData","path":"GSMSystem/updateData","pid":30,"url":"GSMSystem/updateData"}]},{"id":2,"hidden":true,"name":"hbcdmadisplay","path":"/hbcdmadisplay","pid":1,"url":"/hbcdmadisplay","alwaysShow":true,"component":"#","meta":{"icon":"icon","status":true,"title":"CDMA后台"},"children":[{"alwaysShow":true,"component":"/hbcdmadisplay/index","hidden":false,"id":11,"meta":{"icon":"hbcdmadisplay","status":true,"title":"hbcdmadisplay"},"name":"hbcdmadisplay","path":"/hbcdmadisplay","pid":30,"url":"/hbcdmadisplay"}]},{"id":3,"hidden":false,"name":"interception","path":"/interception","pid":2,"url":"/interception","alwaysShow":true,"component":"#","meta":{"icon":"icon","status":true,"title":"截取任务"},"children":[{"alwaysShow":true,"component":"/interception/taskmanagement/index","hidden":false,"id":11,"meta":{"icon":"taskmanagement","status":true,"title":"任务管理"},"name":"taskmanagement","path":"interception/taskmanagement","pid":30,"url":"interception/taskmanagement"}]}]}GsomFormat插件可以直接转译成类即可使用
//这是设计好的类,可以直接使用
import java.util.List;
public class RouterMeunInfo {
public int id;
public boolean hidden;
public String name;
public String path;
public int pid;
public String url;
public boolean alwaysShow;
public String component;
//涉及meta内部集合
public Meta meta;
//设计chilren
public List<Children> children;
public static class Meta{
public String icon;
public boolean status;
public String title;
}
public static class Children{
public boolean alwaysShow;
public String component;
public boolean hidden;
public int id;
public Meta meta;
public String name;
public String path;
public int pid;
public String url;
}
}
至于案列,转译一下json就可以看出来里面的逻辑了。

京公网安备 11010502036488号