其实需求很简单,就是要 vue-element-admin 项目动态的调用接口,后台查询后返回给前端项目,符合你的权限范围内的页面!
(21条消息) 对vue-element-admin从后台动态查询菜单并生成路由信息_acoolper的专栏-优快云博客
如上的一篇文章,受益匪浅,成功实现了我的需求。
但是我遇到了一个文章末尾评论区的通用问题,让我很不爽。
component: () => import(`@/views${item.url}/index`),
我的代码这么写始终报 Module build failed (from ./node_modules/eslint-loader/index.js): TypeError: Cannot read property 'range' of null
让我想到了另外的方法,规避问题:那就是,前台维护好 asyncRoutes , 根据后台请求返回的数据,对 asyncRoutes 进行字段重置。
time to show code
第一处修改:src/store/modules/permission.js
import { asyncRoutes, constantRoutes } from '@/router'
import { getRoutes } from '@/api/user'
/**
* 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
}
}
/**
* 将后台查询的 routes 数据合并到原始的 routes 数据
* @param asyncRoutes 原始 routes 数据
* @param loadRoutes 后台查询到的 routes 数据
*/
export function dealLoadRoutes(asyncRoutes, loadRoutes) {
loadRoutes.forEach(loadRoute => {
// console.log("dealLoadRoutes:" + JSON.stringify(loadRoute))
dealLoadRoute(asyncRoutes, loadRoute)
})
}
/**
* 同级别节点数据合并( path 相同则认为可以合并)
* @param asyncRoutes 原始 routes 数据
* @param loadRoute 后台查询到的 routes 数据,单条
*/
export function dealLoadRoute(asyncRoutes, loadRoute) {
asyncRoutes.forEach(asyncRoute =>{
// 原始路由配置如果和后台查询到的路由配置path相同,则关键字段替换
if(asyncRoute.path == loadRoute.path){
asyncRoute.id = loadRoute.id
asyncRoute.name = loadRoute.name
asyncRoute.meta.title = loadRoute.meta.title
asyncRoute.meta.icon = loadRoute.meta.icon
asyncRoute.meta.roles = loadRoute.meta.roles
console.log("path_match:"+JSON.stringify(asyncRoute))
// 处理children
if(asyncRoute.children){
dealLoadRoutes(asyncRoute.children, loadRoute.children)
}
}
})
}
/**
* 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 loadRoutes = []
// 先查询后台菜单数据并把数据合并到路由
getRoutes(state.token).then(response => {
let data = response
if (response.code != 20000) {
this.$message({
message: 'routes数据加载异常',
type: 0
})
} else {
data = response.data
Object.assign(loadRoutes, data)
dealLoadRoutes(asyncRoutes, loadRoutes)
let accessedRoutes
if (roles.includes('admin')) {
// alert(JSON.stringify(asyncRoutes))
accessedRoutes = asyncRoutes || []
} else {
accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
}
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
}
// generaMenu(asyncRoutes, data)
}).catch(error => {
console.log(error)
})
})
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
第二处修改:src/api/user.js
import request from '@/utils/request'
export function login(data) {
return request({
url: '/vue-element-admin/user/login',
method: 'post',
data
})
}
export function getInfo(token) {
return request({
url: '/vue-element-admin/user/info',
method: 'get',
params: { token }
})
}
export function logout() {
return request({
url: '/vue-element-admin/user/logout',
method: 'post'
})
}
export function getRoutes(token) {
return request({
url: '/vue-element-admin/routes',
method: 'get'
})
}
仅仅如上的两处修改。
另外附加 /vue-element-admin/routes 请求返回的数据格式
{
"code":20000,
"data":[
{
"id":3,
"path":"/permission",
"meta":{
"title":"权限控制",
"icon":"lock",
"roles":["editor"]
},
"children":[
{
"id":4,
"path":"page",
"meta":{
"title":"My Page Permission",
"icon":null,
"roles":["editor","admin"]
},
"children":[]
},
{
"id":5,
"path":"directive",
"meta":{
"title":"My Directive Permission",
"icon":null,
"roles":["admin"]
},
"children":[]
},
{
"id":6,
"path":"role",
"meta":{
"title":"My Role Permission",
"icon":null,
"roles":["admin"]
},
"children":[]
}
]
}
],
"message":"成功"
}
本文介绍如何在Vue项目中实现从后端动态获取路由信息,并通过权限控制显示相应页面。通过修改permission模块和user API,实现了根据用户角色动态加载路由的功能。
2714

被折叠的 条评论
为什么被折叠?



