vue element admin从后端获取数据动态生成路由
登录、获取角色什么这些简单,按照后台调用vuex再调用接口就完事了。
以上截图的例子与后端接口有关,没有接口前端可以也可以自行模拟。先看后端接口返回的数据格式是什么?如果不是树,自行可以根据id关系自行转换一个树。
{
"code": 20000,
"errmsg": "get menutree ok",
"data": [
{
"id": "11",
"parentId": "1",
"path": "/userMsg",
"component": "Layout",
"meta": {
"title": "用户管理",
"icon": "table"
},
"name": "/userMsg",
"children": [
{
"id": "111",
"parentId": "11",
"path": "/user",
"component": "User",
"meta": {
"title": "用户列表1",
"icon": "table"
},
"name": "/user"
},
{
"id": "112",
"parentId": "11",
"path": "/role",
"component": "Role",
"meta": {
"title": "1角色列表",
"icon": "table"
},
"name": "/role"
}
]
},
{
"id": "12",
"parentId": "1",
"path": "/goodMsg",
"component": "Layout",
"meta": {
"title": "商品管理",
"icon": "table"
},
"name": "/goodMsg",
"children": [
{
"id": "121",
"parentId": "12",
"path": "/good",
"component": "Good",
"meta": {
"title": "商品列表2",
"icon": "table"
},
"name": "/good"
},
{
"id": "122",
"parentId": "12",
"path": "/category",
"component": "Category",
"meta": {
"title": "分类列表3",
"icon": "table"
},
"name": "/category"
}
]
}
]
}
重点是 store/modules/permission.js 文件
import { asyncRoutes, constantRoutes } from '@/router'
import { getMuneTree } from '@/api/menu'
// 这几个是视图文件,没有就自己新建文件
import Layout from '@/layout'
import User from '@/views/user/user.vue'
import Role from '@/views/role/role.vue'
import Good from '@/views/good/good.vue'
import Category from '@/views/category/category.vue'
// 组件对象与 后端返回component字段进行的关系映射
const componentMap = {
Layout: Layout,
User: User,
Role: Role,
Good: Good,
Category: Category
}
/**
* 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
}
}
/**
* 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: async function({ commit }, roles) {
// return new Promise(resolve => {
// 获取后端菜单树数据数据
let res = await getMuneTree()
let treeList = res.data
console.log('77777777777777777777', treeList)
// 将后端返回的数据格式处理成 合适的数据格式
for (let i = 0; i < treeList.length; i++) {
delete treeList[i].id
delete treeList[i].parentId
treeList[i].meta.breadcrumb = false
if (treeList[i].component && typeof (treeList[i].component == 'string')) {
treeList[i].component = componentMap[treeList[i].component]
}
if (treeList[i].children) {
for (let k = 0; k < treeList[i].children.length; k++) {
delete treeList[i].children[k].id
delete treeList[i].children[k].parentId
if (
treeList[i].children[k].component &&
typeof (treeList[i].children[k].component == 'string')
) {
treeList[i].children[k].component =
componentMap[treeList[i].children[k].component]
}
}
}
}
console.log('safdkjjjjjjjjj', treeList)
let accessedRoutes
// 前端模拟的数据
// const menus = [
// {
// path: '/userMsg',
// component: Layout,
// name: 'userMsg',
// redirect: '/userMsg/user',
// meta: {
// title: '用户管理',
// icon: 'table'
// },
// children: [
// {
// name: 'user',
// path: '/user',
// component: User,
// meta: {
// title: '用户列表',
// icon: 'table'
// }
// },
// {
// name: 'role',
// path: '/role',
// component: Role,
// meta: {
// title: '角色列表',
// icon: 'table'
// }
// }
// ]
// },
// {
// name: 'goodMsg',
// path: '/goodMsg',
// component: Layout,
// redirect: '/goodMsg/good',
// meta: {
// title: '商品管理',
// icon: 'table'
// },
// children: [
// {
// name: 'good',
// path: '/good',
// component: Good,
// meta: {
// title: '商品列表',
// icon: 'table'
// }
// },
// {
// name: 'category',
// path: '/category',
// component: Category,
// meta: {
// title: '分类列表',
// icon: 'table'
// }
// }
// ]
// }
// ]
// console.log('&&&&&&&&&&&&&&&&&&&&&&&&&&&&&', menus)
console.log(asyncRoutes)
if (roles.includes('admin')) {
accessedRoutes = treeList || []
} else {
accessedRoutes = filterAsyncRoutes(treeList, roles)
}
commit('SET_ROUTES', accessedRoutes)
// resolve(menus)
return treeList
// })
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
代码比较粗糙,但是原理是差不多的。可以凑合着参考。