antd design pro vue 的路由有两种方式 一种是前端定义好路由routes,由后端返回roles进行过滤 ; 另一种是后端返回 routes 列表 生成menu。
一、先看第一种方式 前端定义好路由routes,由后端返回roles进行过滤
1、在src/permission.js 路由守卫 首先在派发一个GetInfo的action 调取getinfo()方法 调后台的 用户接口 返回用户信息和roles用户权限
在src/store/modules/user.js中
// 获取用户信息
GetInfo ({ commit }) {
return new Promise((resolve, reject) => {
getInfo().then(response => {
const result = response.result
if (result.role && result.role.permissions.length > 0) {
const role = result.role
role.permissions = result.role.permissions
role.permissions.map(per => {
if (per.actionEntitySet != null && per.actionEntitySet.length > 0) {
const action = per.actionEntitySet.map(action => { return action.action })
per.actionList = action
}
})
role.permissionList = role.permissions.map(permission => { return permission.permissionId })
commit('SET_ROLES', result.role)
commit('SET_INFO', result)
} else {
reject(new Error('getInfo: roles must be a non-null array !'))
}
// commit('SET_ROLES', result.role)
// commit('SET_INFO', result)
commit('SET_NAME', { name: result.name, welcome: welcome() })
commit('SET_AVATAR', result.avatar)
resolve(response)
}).catch(error => {
reject(error)
})
})
},
通过 role.permissionList = role.permissions.map(permission => { return permission.permissionId })
把返回的权限role的permisssionList字段中 并将roles存储到vuex中
然后继续看在src/permission.js 派发GenerateRoutes action 将 getinfo()的返回 作为 commit参数 传递给 GenerateRoutes 这里注意 在antd pro vue 中 是分成两种路由方式的 默认用第一种前端写死路由方式 所以 在src/store/index.js 注释掉 代码如下
import Vue from 'vue'
import Vuex from 'vuex'
import app from './modules/app'
import user from './modules/user'
// default router permission control
import permission from './modules/permission'
// dynamic router permission control (Experimental)
// import permission from './modules/async-router'
import getters from './getters'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
app,
user,
permission
},
state: {
},
mutations: {
},
actions: {
},
getters
})
然后重点看这个src/strore/modules/permission.js
const permission = {
state: {
routers: constantRouterMap,
addRouters: []
},
mutations: {
SET_ROUTERS: (state, routers) => {
state.addRouters = routers
state.routers = constantRouterMap.concat(routers)
}
},
actions: {
GenerateRoutes ({ commit }, data) {
return new Promise(resolve => {
const { roles } = data
console.log('routerdata', data)
const accessedRouters = filterAsyncRouter(asyncRouterMap, roles)
commit('SET_ROUTERS', accessedRouters)
resolve()
})
}
}
}
export default permission
依赖这个方法 参数为 asyncRouterMap 为 src/config/router.config.js 前端写死的路由表
通过过滤 asyncRouterMap 那route对象里meta的permission字段判断是否包含permissionList数组中 的任何一项
最后将静态路由合并到一起写到vuex中
二、第二种方式 服务端返回routes列表 前端组装成menu树
1、首先 找到src/store/index.js
import Vue from 'vue'
import Vuex from 'vuex'
import app from './modules/app'
import user from './modules/user'
// default router permission control
// import permission from './modules/permission'
// dynamic router permission control (Experimental)
import permission from './modules/async-router'
import getters from './getters'
Vue.use(Vuex)
export default new Vuex.Store({
modules: {
app,
user,
permission
},
state: {
},
mutations: {
},
actions: {
},
getters
})
2、还是找到src/permission.js
派发的GenerateRoutes commit 传token
const permission = {
state: {
routers: constantRouterMap,
addRouters: []
},
mutations: {
SET_ROUTERS: (state, routers) => {
state.addRouters = routers
state.routers = constantRouterMap.concat(routers)
}
},
actions: {
GenerateRoutes ({ commit }, data) {
return new Promise(resolve => {
const { token } = data
generatorDynamicRouter(token).then(routers => {
commit('SET_ROUTERS', routers)
resolve()
})
})
}
}
}
export default permission
在src/router/generator-routers
/**
* 动态生成菜单
* @param token
* @returns {Promise<Router>}
*/
export const generatorDynamicRouter = (token) => {
return new Promise((resolve, reject) => {
loginService.getCurrentUserNav(token).then(res => {
const { result } = res
const menuNav = []
const childrenNav = []
// 后端数据, 根级树数组, 根级 PID
listToTree(result, childrenNav, 0)
console.log('childrenNav3333',childrenNav)
rootRouter.children = childrenNav
menuNav.push(rootRouter)
console.log('menuNav', menuNav)
const routers = generator(menuNav)
routers.push(notFoundRouter)
console.log('routers', routers)
resolve(routers)
}).catch(err => {
reject(err)
})
})
}
通过listTotree动态生成menu
/**
* 数组转树形结构
* @param list 源数组
* @param tree 树
* @param parentId 父ID
*/
const listToTree = (list, tree, parentId) => {
list.forEach(item => {
// 判断是否为父级菜单
if (item.parentId === parentId) {
const child = {
...item,
key: item.key || item.name,
children: []
}
// 迭代 list, 找到当前菜单相符合的所有子菜单
listToTree(list, child.children, item.id)
// 删掉不存在 children 值的属性
if (child.children.length <= 0) {
delete child.children
}
// 加入到树中
tree.push(child)
}
})
}