最近使用vue-element-template模板做系统时,需要实现用户权限管理,通过后端传来的roles字段来判断不同用户的身份,不同用户显示不同的侧边栏,下面是配置方法:
0.需要配置的文件有:
- src/router
- src/store/modules/permission.js (没有就添加)
- src/store/modules/user.js
- src/store/index
- src/permission.js
- src/store/getters.js
1.首先修改 src/router中代码:
把需要权限的加在 asyncRoutes 里面 ,相应权限就用roles: ['admin']放不同的用户类型来控制。
constantRoutes里面放静态路由,所有人可见
具体参考下面代码:
import Vue from 'vue'
import Router from 'vue-router'
// 路由是个插件,需要use
Vue.use(Router)
// 引入layout组件,一级路由出口中,匹配layout组件
import Layout from '@/layout'
// 静态路由,所有人可见
export const constantRoutes = [
{
path: '/login',
component: () => import('@/views/login/index'),
// hidden为true表示在侧边栏不显示
hidden: true
},
{
path: '/404',
component: () => import('@/views/404'),
hidden: true
},
{
path: '/',
component: Layout,
redirect: '/dashboard',
// 二级路由
children: [{
path: 'dashboard',
name: 'Dashboard',
component: () => import('@/views/dashboard/index'),
meta: { title: '首页', icon: 'dashboard' }
}]
},
// 404 page must be placed at the end !!!
{ path: '*', redirect: '/404', hidden: true }
]
//相应权限人员可见
export const asyncRoutes = [
{
path:'/patentupload',
component:Layout,
name:'Patentupload',
meta:{ title: '专利上传', icon: 'el-icon-s-promotion',roles: ['admin'] },
children: [{
path: 'singleupload',
name: 'Singleupload',
component: () => import('@/views/patentupload/singleload'),
meta: { title: '单条专利上传',roles: ['admin'] }
},
{
path: 'multipleload',
name: 'Multipleload',
component: () => import('@/views/patentupload/multipleload'),
meta: { title: '多条专利上传',roles: ['admin'] }
},
]
},
{
path:'/expertrate',
component:Layout,
name:'Expertrate',
meta:{ title: '专家打分系统', icon: 'el-icon-notebook-2',roles: ['editor'] },
children: [{
path: 'unratedpatents',
name: 'Unratedpatents',
component: () => import('@/views/expertrate/unratedpatents'),
meta: { title: '未打分专利',roles: ['editor'] }
},
{
path: 'ratedpatents',
name: 'Ratedpatents',
component: () => import('@/views/expertrate/ratedpatents'),
meta: { title: '已打分专利',roles: ['editor'] }
},
{
path: 'rate',
name: 'Rate',
component: () => import('@/views/expertrate/rate'),
meta: { title: '打分界面',roles: ['editor'] }
},
]
},
]
// 创建一个路由对象
const createRouter = () => new Router({
// mode: 'history', // require service support
scrollBehavior: () => ({ y: 0 }),
routes: constantRoutes
})
const router = createRouter()
// Detail see: https://github.com/vuejs/vue-router/issues/1234#issuecomment-357941465
export function resetRouter() {
const newRouter = createRouter()
router.matcher = newRouter.matcher // reset router
}
export default router
2. src/store/modules/permission.js (没有就添加)
generateRoutes函数来控制你设置的每个用户的判断操作,如果有超过两个的用户就继续添加ifelse。代码如下:
import { asyncRoutes, constantRoutes } from '@/router'
// 筛选路由
// 匹配权限
function hasPermission( roles, route) {
// 在路由上找的到 route.mate 和 route.mate.roles
if (route.meta && route.meta.roles){
return roles.some(role => route.meta.roles.includes(role))
}else{
return true
}
}
// 通过递归过滤异步路由表
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 =>{
let accessedRoutes
// 路由是否为 admin, 有直接全部显示
if(roles.includes('admin')){
accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
// accessedRoutes = asyncRoutes || []
console.log('走了这里1 ',accessedRoutes)
console.log('asyncRoutes ',asyncRoutes)
}else{
// 过滤路由
accessedRoutes = filterAsyncRoutes(asyncRoutes, roles)
console.log('走了这里2 ')
}
commit('SET_ROUTES', accessedRoutes)
resolve(accessedRoutes)
})
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
3.src/store/modules/user.js 代码如下:
import { login, logout, getInfo } from '@/api/user'
import { getToken, setToken, removeToken } from '@/utils/auth'
import { resetRouter } from '@/router'
const getDefaultState = () => {
return {
token: getToken(),
name: '',
avatar: '',
roles:[], //权限设置
introduction:'', // 新增
}
}
const state = getDefaultState()
const mutations = {
RESET_STATE: (state) => {
Object.assign(state, getDefaultState())
},
SET_TOKEN: (state, token) => {
state.token = token
},
// 新增
SET_INTRODUCTION: (state, introduction) => {
state.introduction = introduction
},
SET_NAME: (state, name) => {
state.name = name
},
SET_AVATAR: (state, avatar) => {
state.avatar = avatar
},
//权限设置
SET_ROLES: (state, roles) => {
state.roles = roles
}
}
const actions = {
// user login
login({ commit }, userInfo) {
const { username, password } = userInfo
// let result= await login({username:username.trim(),password:passwora});
return new Promise((resolve, reject) => {
login({ username: username.trim(), password: password }).then(response => {
const { data } = response
commit('SET_TOKEN', data.token)
setToken(data.token)
resolve()
}).catch(error => {
reject(error)
})
})
},
// get user info
getInfo({ commit, state }) {
return new Promise((resolve, reject) => {
getInfo(state.token).then(response => {
const { data } = response
if (!data) {
return reject('Verification failed, please Login again.')
}
// const { name, avatar } = data
const {roles, name, avatar, introduction } = data//权限设置
// 必须保证不是一个空的数组
if(!roles || roles.length<=0 ){//权限设置
reject('getInfo: roles must be a non-null array')//权限设置
}//权限设置
console.log(roles)//权限设置
// 存储值
commit('SET_NAME', name)
commit('SET_ROLES', roles) //权限设置
commit('SET_AVATAR', avatar)
commit('SET_INTRODUCTION', introduction)//权限设置
resolve(data)
}).catch(error => {
reject(error)
})
})
},
// user logout
logout({ commit, state }) {
return new Promise((resolve, reject) => {
logout(state.token).then(() => {
commit('SET_TOKEN', '')//权限设置
commit('SET_ROLES', []) //权限设置
removeToken() // must remove token first
resetRouter()
commit('RESET_STATE')
resolve()
}).catch(error => {
reject(error)
})
})
},
// remove token
resetToken({ commit }) {
return new Promise(resolve => {
commit('SET_TOKEN', '')//权限设置
commit('SET_ROLES', []) //权限设置
removeToken() // must remove token first
commit('RESET_STATE')
resolve()
})
}
}
export default {
namespaced: true,
state,
mutations,
actions
}
4.src/store/index 代码如下:
import Vue from 'vue'
import Vuex from 'vuex'
import getters from './getters'
import app from './modules/app'
import settings from './modules/settings'
import user from './modules/user'
// 权限设置
import permission from './modules/permission'
Vue.use(Vuex)
const store = new Vuex.Store({
modules: {
app,
settings,
user,
permission // 权限设置
},
getters
})
export default store
5.src/permission.js 代码如下:
// 引入路由器router
import router from './router'
// 引入仓库
import store from './store'
// 引入ele的提示组件
import { Message } from 'element-ui'
// 引入交互进度条
import NProgress from 'nprogress' // progress bar
import 'nprogress/nprogress.css' // progress bar style
// 从cookie中获取token,登录了就有cookie
import { getToken } from '@/utils/auth' // get token from cookie
// 得到页面的title
import getPageTitle from '@/utils/get-page-title'
// 配置nprogress
NProgress.configure({ showSpinner: false }) // NProgress Configuration
// 白名单,不需要登录就能进入的路由
const whiteList = ['/login'] // no redirect whitelist
// 全局前置路由守卫
router.beforeEach(async(to, from, next) => {
//开启进度条
NProgress.start()
//给页面的title赋值
document.title = getPageTitle(to.meta.title)
// 从cookie中拿到token,有的话就放行,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()
} else {
// 获取用户信息
// const hasGetUserInfo = store.getters.name
const hasRoles = store.getters.roles && store.getters.roles.length > 0// 权限控制
console.log('roles:',store.getters.roles)
// if (hasGetUserInfo) {
if (hasRoles) {
console.log('执行了1')
next()
} else {
console.log('执行了2')
try {
// get user info 重新获取用户信息
// await store.dispatch('user/getInfo')
// 权限控制
const { roles } = await store.dispatch('user/getInfo')
// 在角色权限基础上生成动态路由表
const accessRoutes = await store.dispatch('permission/generateRoutes', roles)
console.log('accessRoutes:',accessRoutes)
router.options.routes = store.getters.permission_routes
// 动态添加可访问路由
router.addRoutes(accessRoutes)
console.log('输出的store:',store)
next({...to, replace: true })
// next()
} 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()
}
}
}
} 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()
})
6.src/store/getters.js:
const getters = {
sidebar: state => state.app.sidebar,
device: state => state.app.device,
token: state => state.user.token,
avatar: state => state.user.avatar,
name: state => state.user.name,
// 权限设置
roles: state => state.user.roles,
permission_routes: state => state.permission.routes
}
export default getters
经过上面的配置,应该就可以完成权限管理了。如果有问题的话留言评论