Skip to content
生如风生如风
主页
github icon
  • 后端
    • 前端
      • 效果
        • 报错(补充记录产生的问题,可不看)
          • 总结

            vue-admin-template学习(四)

            author icon生如风calendar icon2021年3月20日category icon
            • Vue
            tag icon
            • Vue
            • vue-admin-template
            timer icon大约 5 分钟

            此页内容
            • 后端
            • 前端
            • 效果
            • 报错(补充记录产生的问题,可不看)
            • 总结

            # vue-admin-template角色的权限判断

            # 后端

            实现获取用户角色的方法挺多的,比如:

            • 可以单独写一个通过用户标识获取用户的roles接口
            • 可以在用户登录成功后,返回用户的信息中加入用户的roles信息,我的项目目前用的是这个,所以会以这个写一下记录

            实现:

            // 设置角色
            Set<String> rolesSet = roleService.getUserRolesSet(user.getUsername());
            
            return Result.success(MapUtil.builder()
                    .put("id", user.getId())
                    .put("username", user.getUsername())
                    .put("avatar", user.getAvatar())
                    .put("email", user.getEmail())
                    .put("roles", rolesSet)
                    .map());
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10

            rolesSet打印:

            System.out.println("角色集合======" + rolesSet);
            
            
            角色集合======[admin]
            或者
            角色集合======[admin,editor]
            
            1
            2
            3
            4
            5
            6

            # 前端

            通过登录成功后,将用户的roles信息储存到store中,引入permission调取store中的roles信息,在组件中通过v-permission进行权限判断

            实现:

            在store的user.js中

            定义user对象:

            state: {
                token: '',
                name: '',
                avatar: '',
                userInfo: JSON.parse(sessionStorage.getItem('userInfo')),
                // 该roles定义为数组
                roles: [],
              },
            
              mutations: {
                // set
                SET_TOKEN: (state, token) => {
                  state.token = token
                  localStorage.setItem('token', token)
                },
            
                SET_USERINFO: (state, userInfo) => {
                  state.userInfo = userInfo
                  sessionStorage.setItem('userInfo', JSON.stringify(userInfo))
                },
            
                REMOVE_INFO: (state) => {
                  state.token = ''
                  state.userInfo = {}
                  state.avatar = ''
                  // 记得此处也要还原为数组,否则会产生文末的报错信息
                  state.roles = []
                  localStorage.setItem('token', '')
                  sessionStorage.setItem('userInfo', JSON.stringify(''))
                },
            
                SET_NAME: (state, name) => {
                  state.name = name
                },
                SET_AVATAR: (state, avatar) => {
                  state.avatar = avatar
                },
                SET_ROLES: (state, roles) => {
                  state.roles = roles
                },
            }
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21
            22
            23
            24
            25
            26
            27
            28
            29
            30
            31
            32
            33
            34
            35
            36
            37
            38
            39
            40
            41

            登录请求:

            Login({ commit }, userInfo) {
                  const username = userInfo.username.trim()
                  return new Promise((resolve, reject) => {
                    login(username, userInfo.password).then(response => {
                      const jwt = response.headers['authorization']
                      const userInfo = response.data.data
            
                      commit('SET_TOKEN', jwt)
                      commit('SET_USERINFO', userInfo)
                      commit('SET_AVATAR', userInfo.avatar)
                      commit('SET_NAME', userInfo.username)
                      // 将获取到的角色数据赋值
                      commit('SET_ROLES', userInfo.roles)
                      resolve()
                    }).catch(error => {
                      reject(error)
                    })
                  })
                },
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19

            引入下面链接的permission:

            https://github.com/PanJiaChen/vue-element-admin/tree/master/src/directive/permission

            使用:

            v-permission="['admin','editor']"判断该按钮、模块是否可见
            
            1
            <el-button v-permission="['admin','editor']" size="mini" type="primary" @click="handleDownloadFile(scope.row.fileUrl,offStyle)">
            下载
            </el-button>
            
            1
            2
            3

            # 效果

            检验前:

            img点击并拖拽以移动

            检验后:

            img点击并拖拽以移动

            这样,就做到了按钮的权限控制,模块类似。

            但是,这时,我并不想把按钮隐藏起来,想把按钮变成**“禁用”**状态

            如下:

            img点击并拖拽以移动

            这样,“下载”按钮就变成了禁用状态了,鼠标移上去会有禁用图标出现,无法点击。

            实现:

            (1)将https://github.com/PanJiaChen/vue-element-admin/tree/master/src/utils中的permission.js的工具类引入项目,要不就自己写一个检查store中的roles数据的方法

            引入的permission.js:

            import store from '@/store'
            
            /**
             * @param {Array} value
             * @returns {Boolean}
             * @example see @/views/permission/directive.vue
             */
            export default function checkPermission(value) {
              if (value && value instanceof Array && value.length > 0) {
                const roles = store.getters && store.getters.roles
                const permissionRoles = value
            
                const hasPermission = roles.some(role => {
                  return permissionRoles.includes(role)
                })
                return hasPermission
              } else {
                console.error(`need roles! Like v-permission="['admin','editor']"`)
                return false
              }
            }
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18
            19
            20
            21

            可以看出来,调用需要传入一个value值,和v-permission="['admin']"中['admin']所需要的一样,上面引入的permission模块中的主要方法和utils中的permission.js类似

            (2)引入完成后,在view界面中,引入utils下的permission.js用于检验权限

            import checkPermission from '@/utils/permission' // 权限判断函数
            
            methods: {
               // 定义方法
               checkPermission,
               handleRolesChange() {
                 this.key++
              }
            }
            
            1
            2
            3
            4
            5
            6
            7
            8
            9

            vue中,使用disabled控制“禁用状态” ,disabled="true"为禁用,为false为不禁用

            <el-button :disabled="!checkPermission(['admin'])" size="mini" type="primary" @click="handleDownloadFile(scope.row.fileUrl,offStyle)">
            下载
            </el-button>
            
            1
            2
            3

            到这,暂时实现了想要实现的基本功能

            另外:在上文中,我将store中的roles直接赋值了,这样vue路由重载后会丢失,所以建议用sessionStore或localStore存储起来

            # 报错(补充记录产生的问题,可不看)

            下面的报错是在进入到使用v-permission判断的vue界面后,退出系统时闪过的异常,截图发现

            img点击并拖拽以移动

            报错内容为引入的permission中的roles.some is not a function,查看permission.js中,有代码:

            const hasPermission = roles.some(role => {
                    return permissionRoles.includes(role)
                  })
            
            1
            2
            3

            可以定位到此处的报错。

            (1)发现在上面“定义user对象”时,roles已经被定义为了数组

            (2)刚开始时,在REMOVE_INFO中,我的roles还原直接是state.roles=' '

            (3)在登录成功后,并且进入使用了v-permission的页面时,还未抛出该错误,但是当退出系统时就抛出了,于是猜想可能就是退出系统时,未将state.roles还原为空数组,所以报错。

            解决:将REMOVE_INFO中的state.roles=' '修改为state.roles=[]

            这样测试之后,系统正常。

            # 总结

            这里总结一下在项目中view页面用到的几种判断方法:

            第一种:设置为不可见

            // 使用v-permission="['admin','editor']"
            
            
            <el-button v-permission="['admin','editor']" size="mini" type="primary" @click="handleDownloadFile">
            下载
            </el-button>
            
            1
            2
            3
            4
            5
            6

            第二种:设置为不可见

            // 使用v-if="checkPermission['admin']"
            
            <el-tab-pane v-if="checkPermission(['admin'])" label="Admin">
                Admin can see this
                <el-tag class="permission-sourceCode" type="info">
                    v-if="checkPermission(['admin'])"
                </el-tag>
            </el-tab-pane>
            
            1
            2
            3
            4
            5
            6
            7
            8

            第三种:设置为禁用状态

            <el-button :disabled="!checkPermission(['admin','editor'])" size="mini" type="primary" @click="handleDownloadFile()">
            按钮禁用方式
            </el-button>
            
            1
            2
            3

            第四种:设置为禁用状态

            该方法设置标签的style css

            <template slot-scope="scope">
               <span :style="!checkPermission(['admin','editor'])===true?spanForbid:spanNormal" 
                      class="link-type" @click="handleUpdate(scope.row)">
               span禁用方式
               </span>
            </template>
            
            
            data() {
              return {
                spanForbid: {
                  // color: 'grey',  设置颜色为灰色
                  cursor: 'not-allowed'
                  // pointerEvents: 'none'为鼠标无法点击,cursor为出现禁用icon,两者无法同时显示
                 },
                spanNormal: {}
              }
            }
            
            1
            2
            3
            4
            5
            6
            7
            8
            9
            10
            11
            12
            13
            14
            15
            16
            17
            18

            ————————————————————— 作为初学者,很多前端的知识都没有掌握,见谅,如有错误请指出,以期进步,感谢!。后续有新的学习,继续补充上来。

            默认页脚
            Copyright © 2026 生如风