zoukankan      html  css  js  c++  java
  • vue-admin-element 精确到按钮的权限管理

    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>
        
  • 相关阅读:
    Spring Boot笔记一 输出hello
    Java Web之表单重复提交问题
    Java Web之验证码
    Java Web之下载文件
    Java工具之上传文件
    Java Web之上传文件
    Java Web之EL
    Java Bean的规范
    Java Web之JSP
    《FPGA全程进阶---实战演练》第一章之如何学习FPGA
  • 原文地址:https://www.cnblogs.com/wuxiaoshi/p/13582183.html
Copyright © 2011-2022 走看看