vue-admin-element 权限管理
-
菜单栏权限问题
-
在
router/index.js
中 添加需要的动态路由,其它不变export const asyncRoutes = [{ path: '/form', name: 'Form', component: Layout, meta: { title: 'Form', icon: 'lock', roles: ['admin', 'editor'] // 角色信息 }, children: [{ path: 'index', component: () => import('@/views/form/index'), name: 'Form', meta: { title: 'Form', icon: 'icon', roles: ['admin', 'editor'] // 角色信息 } }] } ]
-
在
src/permission.js
中根据角色获取异步的路由信息import router from './router' import store from './store' import { Message } 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' //----- 添加的内容 开始 ------------- import { constantRoutes } from '@/router' //----- 添加的内容 结束 ------------- NProgress.configure({ showSpinner: false }) // NProgress Configuration const whiteList = ['/login'] // 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() } else { const hasGetUserInfo = store.getters.name if (hasGetUserInfo) { next() } else { try { // 获取用户角色 // ----------添加内容开始 ------------------ const {rules} = await store.dispatch('user/getInfo') const accessRoutes = await store.dispatch('user/generateRoutes', rules) const routes = constantRoutes.concat(accessRoutes) router.options.routes = routes // 拼接數組 router.addRoutes(routes) 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() } } } } 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() })
-
src/store/modules/user.js
文件中添加generateRoutes
方法import { login, logout, getInfo } from '@/api/user' import { getToken, setToken, removeToken } from '@/utils/auth' // -------添加 导入路由 信息 开始 --------- import { resetRouter, asyncRoutes, constantRoutes } from '@/router' // -------添加 导入路由 信息 结束 --------- const getDefaultState = () => { return { token: getToken(), name: '', avatar: '', rules: [], routes: [], // 该角色拥有的权限信息 addRoutes: [] // 该角色新增的权限信息 } } const state = getDefaultState() const mutations = { RESET_STATE: (state) => { Object.assign(state, getDefaultState()) }, SET_TOKEN: (state, token) => { state.token = token }, SET_NAME: (state, name) => { state.name = name }, SET_AVATAR: (state, avatar) => { state.avatar = avatar }, // -----------添加 mutations 开始 ------------------- SET_RULES: (state, rules) => { state.rules = rules }, SET_ROUTES: (state, routes) => { state.addRoutes = routes state.routes = constantRoutes.concat(routes) } // -----------添加 mutations 结束 ------------------- } // ------------------添加 是否有权限 方法开始------------------------------ function hasPermission(rules, route) { if (route.meta && route.meta.roles) { return roles.some(rules => route.meta.roles.includes(rules)) } else { return true } } // ------------------添加 是否有权限 方法结束------------------------------ // ------------------添加 根据角色过滤动态路由 方法开始------------------------------ export function filterAsyncRoutes(routes, rules) { const res = [] routes.forEach(route => { const tmp = { ...route } if (hasPermission(rules, tmp)) { if (tmp.children) { tmp.children = filterAsyncRoutes(tmp.children, rules) } res.push(tmp) } }) return res } // ------------------添加 根据角色过滤动态路由 方法结束------------------------------ const actions = { // user login login({ commit }, userInfo) { const { username, password } = userInfo 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().then(response => { const { data } = response if (!data) { return reject('Verification failed, please Login again.') } const { name, avatar, rules } = data commit('SET_NAME', name) commit('SET_RULES', rules) commit('SET_AVATAR', avatar) resolve(data) }).catch(error => { reject(error) }) }) }, // user logout logout({ commit, state }) { return new Promise((resolve, reject) => { logout(state.token).then(() => { removeToken() // must remove token first resetRouter() commit('RESET_STATE') resolve() }).catch(error => { reject(error) }) }) }, // remove token resetToken({ commit }) { return new Promise(resolve => { removeToken() // must remove token first commit('RESET_STATE') resolve() }) }, // ------------------添加 生成动态路由 方法开始------------------------------ generateRoutes({ commit }, rules) { return new Promise(resolve => { let accessedRoutes = filterAsyncRoutes(asyncRoutes, rules) commit('SET_ROUTES', accessedRoutes) resolve(accessedRoutes) }) } // ------------------添加 生成动态路由 方法结束------------------------------ } export default { namespaced: true, state, mutations, actions }
-
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, addRoutes: state => state.user.addRoutes, routes: state => state.user.routes, rules: state => state.user.rules } export default getters
-
-
精确到按钮级别
-
在
src/store/modules
创建 js文件btnPermission.js
import Vue from 'vue' import store from '../index' /**权限指令**/ Vue.directive('has', { bind: function (el, binding) { console.log(binding); let Permissions = binding.value; // v-has 绑定的属性,也就是按钮权限值 console.log('permission', Permissions) if (!Vue.prototype.$_has(Permissions)) { let className = el.getAttribute("class") className = className ? className.concat(" wuxiaoshi-btn-hidden") : "wuxiaoshi-btn-hidden"; el.setAttribute("class", className) } } }); //权限检查方法 Vue.prototype.$_has = function (value) { let isExist = false; let buttonpermsStr = store.getters.roles; if (buttonpermsStr == undefined || buttonpermsStr == null) { return false; } for (let i = 0; i < buttonpermsStr.length; i++) { if (value == buttonpermsStr[i]) { isExist = true; break; } } return isExist; };
-
在
src/store/modeles/user.js
中 将权限规则添加到vuex
中const mutations = { RESET_STATE: (state) => { Object.assign(state, getDefaultState()) }, SET_TOKEN: (state, token) => { state.token = token }, SET_NAME: (state, name) => { state.name = name }, SET_AVATAR: (state, avatar) => { state.avatar = avatar }, SET_RULES:(state,rules)=>{ state.rules = rules; } }
-
在
src/store/modeles/user.js
文件中 定义按钮级别权限// 请求后端接口,需要将rules作为一个键将所有的权限信息添加到vuex中 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,rules } = data // 将权限导出来 commit('SET_NAME', name) commit('SET_AVATAR', avatar) commit('SET_RULES', rules) // 添加权限 resolve(data) }).catch(error => { reject(error) }) }) },
-
在
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, rules: state => state.user.rules //获取vuex中的权限信息 } export default getters
-
在
main.js
导入import has from '@/store/modules/btnPermission.js'
-
在
App.vue
中 添加样式<style> .wuxiaoshi-btn-hidden { display: none; } </style>
-