1.统一服务端返回数据
{
"code": 0,
"message": "获取成功",
"data": {
"user_name": "操作员1号",
"user_avatar": "https://fanyi-cdn.cdn.bcebos.com/static/translation/img/header/logo_e835568.png",
"introduction": "-",
"roles": [
"admin"
],
"role_auth": [
{
"path": "/error",
"component": "Layout",
"redirect": "noRedirect",
"name": "ErrorPages",
"meta": {
"title": "Error Pages",
"icon": "404"
},
"children": [
{
"path": "401",
"component": "Page401",
"name": "Page401",
"meta": {
"title": "Page 401",
"noCache": true
}
},
{
"path": "404",
"component": "Page404",
"name": "Page404",
"meta": {
"title": "Page 404",
"noCache": true
}
}
]
}
]
},
"status": 200
}
roles 为角色名称;role_auth 为角色权限列表 ;role_auth 中的 component 对应步骤2的文件位置变量,其他格式可参考 src/route/index 里面路由格式
2.注释本地多余路由地址,添加服务端获取的路由
修改 src/store/modules/user.js
const state = {
、、、
roleAuth: []
}
const mutations = {
、、、
SET_ROLE_AUTH: (state, roleAuth) => {
state.roleAuth = roleAuth
}
}
const actions = {
、、、
getInfo({ commit, state }) {
return new Promise((resolve, reject) => {
getInfo().then(response => {
const { data } = response
if (!data) {
reject('Verification failed, please Login again.')
}
const { roles, user_name, user_avatar, introduction, role_auth } = data
// roles must be a non-empty array
// if (roles === null) {
// reject('getInfo: roles must be a non-null array!')
// }
if (roles !== null) {
// reject('getInfo: roles must be a non-null array!')
commit('SET_ROLES', roles) // 管理员角色名称
}
commit('SET_NAME', user_name)
commit('SET_AVATAR', user_avatar)
commit('SET_INTRODUCTION', introduction)
commit('SET_ROLE_AUTH', role_auth) // 管理员权限列表
resolve(data)
}).catch(error => {
reject(error)
})
})
}
、、、
}
修改 src/router/index.js , 以下变量只保留一个路由
/**
* 路由的文件位置数组
* 每新增一个路由,就需要新增一个变量
*/
export const routerMap = {
Layout: () => import('@/layout'),
Page401: () => import('@/views/error-page/401'), // 用户列表
Page404: () => import('@/views/error-page/404') // 用户列表
}
/**
* TODO 只保留一个路由
*/
export const asyncRoutes = [
/** when your routing map is too long, you can split it into small modules **/
// 404 page must be placed at the end !!!
{ path: '*', redirect: '/404', hidden: true }
]
修改 src/store/modules/permission.js
import { routerMap } from '@/router/index' // 导入路由的文件位置数组变量
import store from '@/store' // 获取store数据
/**
* 新增方法
* 递归过滤异步服务器路由表,返回符合用户角色权限的路由表
* @param routes asyncRouterMap
* @param roles
*/
function filterAsyncServerRolesRouter(roles) {
const res = []
roles.forEach(role => {
const tmp = { ...role }
var tmpComponent = tmp.component
tmp.component = routerMap[tmpComponent]
if (tmp.children) {
tmp.children = filterAsyncServerRolesRouter(tmp.children)
}
res.push(tmp)
})
return res
}
// 修改方法
const actions = {
generateRoutes({ commit }, roles) {
return new Promise(resolve => {
const roleAuth = store.getters && store.getters.roleAuth
let accessedRoutes
let serverRouters
if (roles.includes('admin')) {
accessedRoutes = asyncRoutes || []
} else {
accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
}
// 获取服务器的路由
if (roleAuth) {
serverRouters = filterAsyncServerRolesRouter(roleAuth)
accessedRoutes = serverRouters.concat(accessedRoutes)
}
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
})
}
}
3.获取权限数据时,添加加载层
修改 src/permission.js
import router from './router'
import store from './store'
import { Message, Loading } from 'element-ui'
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
import { getToken } from '@/utils/auth' // get token from cookie
import getPageTitle from '@/utils/get-page-title'
NProgress.configure({ showSpinner: false }) // NProgress Configuration
const whiteList = ['/login', '/auth-redirect'] // no redirect whitelist
router.beforeEach(async(to, from, next) => {
// start progress bar
NProgress.start()
// set page title
document.title = getPageTitle(to.meta.title)
// determine whether the user has logged in
const hasToken = getToken()
if (hasToken) {
if (to.path === '/login') {
// if is logged in, redirect to the home page
next({ path: '/' })
NProgress.done() // hack: https://github.com/PanJiaChen/vue-element-admin/pull/2939
} else {
// determine whether the user has obtained his permission roles through getInfo
const hasRoles = store.getters.roles && store.getters.roles.length > 0
if (hasRoles) {
next()
} else {
const loadingInstance = Loading.service({ fullscreen: true, text: '加载中' }) // TODO 新增
try {
// get user info
// note: roles must be a object array! such as: ['admin'] or ,['developer','editor']
const { roles } = await store.dispatch('user/getInfo')
// generate accessible routes map based on roles
const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
// dynamically add accessible routes
router.addRoutes(accessRoutes)
// hack method to ensure that addRoutes is complete
// set the replace: true, so the navigation will not leave a history record
next({ ...to, replace: true })
} catch (error) {
// remove token and go to login page to re-login
await store.dispatch('user/resetToken')
Message.error(error || 'Has Error')
next(`/login?redirect=${to.path}`)
NProgress.done()
}
loadingInstance.close() // TODO 新增
}
}
} else {
/* has no token*/
if (whiteList.indexOf(to.path) !== -1) {
// in the free login whitelist, go directly
next()
} else {
// other pages that do not have permission to access are redirected to the login page.
next(`/login?redirect=${to.path}`)
NProgress.done()
}
}
})
router.afterEach(() => {
// finish progress bar
NProgress.done()
})