前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >vue项目中前端鉴权实现(菜单权限,按钮权限)

vue项目中前端鉴权实现(菜单权限,按钮权限)

作者头像
子夜星辰
发布2022-11-15 16:24:41
1.5K0
发布2022-11-15 16:24:41
举报
文章被收录于专栏:李白偷偷偷猪李白偷偷偷猪

这段时间比较忙,参与了公司一个新的B端项目的研发,从无到有搭建项目的过程中,遇到了关于项目鉴权的问题,和后端同事讨论了一下思路,自己也找了这方面的资料,整理如下文

权限管理分类:

1,菜单权限控制(页面级)

2,按钮权限控制(按钮级)

3,接口权限控制(url级别)

目前根据项目需求,实现了页面级和按钮级权限控制。

从实现思路来说,很简单,在用户输入用户名密码登录的时候,后台会返回该角色的权限集合,前端获取到录入本地存储中,建议使用sessionStorage,在生成菜单的时候通过查询sessionStorage中是否返回了该权限控制菜单展示,返回形式可以前后端协商,菜单级权限按照菜单目录返回,按钮权限通过list返回,可以是id的集合,也可以是特殊字段的集合,数据库增加一张相对应的映射表。

接下里结合实际例子来说明

首先,用户登录成功从后台获取到权限集合,在接口返回200后,获取到权限集合存入本地存储

代码语言:javascript
复制
 // 登录成功获取权限
   window.sessionStorage.setItem('menuList', JSON.stringify(res.data.menuList))
   window.sessionStorage.setItem('permissions', JSON.stringify(res.data.permissions))

菜单权限控制

菜单的构建

代码语言:javascript
复制
...
<div class="menuContent">
   <Menu :menuList="menuList"></Menu>
</div>
...

菜单组件如下:可根据自己定义数据格式修改 

代码语言:javascript
复制
<template>
  <div class="menuContent">
    <template v-for="list in menuList">
      <el-submenu v-if="list.children != undefined && list.children.length > 0 && list.show == true" :key="list.title" :index="list.path">
        <template slot="title">
          <!-- <i class="el-icon-menu"></i> -->
          {{ list.title}}
        </template>
        <Menu v-if="list.children != undefined && list.children.length > 0 && list.show == true" :menuList="list.children"></Menu>
      </el-submenu>
      <el-menu-item v-if="(list.children == undefined || list.children.length == 0) && list.show == true" :index="list.path" :key="list.title">
        {{list.title}}
      </el-menu-item>
    </template>
  </div>
</template>

<script>
export default {
  name: 'Menu',
  props: ['menuList'],
  data () {
    return {}
  },
  methods: {
  }
}
</script>
<style lang='scss' scoped>
</style>

 菜单数据格式如下:

代码语言:javascript
复制
menuList: [
        {
          path: '/overview',
          title: '首页',
          children: [],
          show: ''
        },
        {
          path: '/resource',
          title: 'a页面',
          show: '',
          children: [
            {
              path: '/physical',
              title: 'a1页面',
              show: ''
            },
            {
              path: '/logic',
              title: 'a2页面',
              show: ''
            },
            {
              path: '/pool',
              title: 'a3页面',
              show: ''
            }
          ]
        },
        {
          path: '/blockStorage',
          title: 'b页面',
          show: '',
          children: [
            {
              path: '/rbdService',
              title: 'b1页面',
              show: ''
            },
            {
              path: '/mapManagement',
              title: 'b2页面',
              show: ''
            },
            {
              path: '/client',
              title: 'b3页面',
              show: ''
            },
            {
              path: '/snapshot',
              title: 'b4页面',
              show: ''
            }
          ]
        },
        {
          path: '/object',
          title: 'c页面',
          show: '',
          children: [
            {
              path: '/objectUser',
              title: 'c1页面',
              show: ''
            },
            {
              path: '/bucket',
              title: 'c2页面',
              show: ''
            }
          ]
        }
      ]

在菜单页面js中增加方法处理

代码语言:javascript
复制
getMenu () {
      this.menuList.forEach(menu => {
        menu.show = this.hasPermiss(menu.title)
        if (menu.children.length > 0) {
          menu.children.forEach(q => {
            q.show = this.hasPermiss(q.title)
          })
        }
      })
    },
// 通过获取缓存中的菜单list比较判断是否展示该菜单
hasPermiss (val) {
      const menuArr = JSON.parse(window.sessionStorage.getItem('menuList'))
      return menuArr.some(item => item.name == val)
      // return true
    }

由于在开发过程中,前后端配置的menuList格式不统一,所以加了二次处理,如果格式统一则可以直接使用本地存储中的菜单,这样就实现了菜单的权限控制

按钮菜单控制

vue提供了自定义指令,可以通过该方法来实现按钮权限控制,核心思路不变,通过按钮处传入权限id/字符,通过遍历缓存起来的按钮权限list,判断是否拥有该权限

核心方法如下

代码语言:javascript
复制
import { checkAuthority } from '@/utils/authority'
export default {
  inserted (el, binding, vnode) {
    const { value } = binding
    const permissions = JSON.parse(sessionStorage.getItem('permissions')) || []
    const hasPermission = checkAuthority(value, permissions)
    if (!hasPermission) {
      // eslint-disable-next-line no-unused-expressions
      if (el.parentNode) {
        el.parentNode.removeChild(el)
      } else {
        el.innerHTML = ''
      }
    } else {
      el && el.setAttribute('code', value)
    }
  },
}

 关于自定义指令如何使用,可以下去自行查找,自己写出来的,印象更加深刻

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-09-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 权限管理分类:
  • 菜单权限控制
  • 按钮菜单控制
相关产品与服务
对象存储
对象存储(Cloud Object Storage,COS)是由腾讯云推出的无目录层次结构、无数据格式限制,可容纳海量数据且支持 HTTP/HTTPS 协议访问的分布式存储服务。腾讯云 COS 的存储桶空间无容量上限,无需分区管理,适用于 CDN 数据分发、数据万象处理或大数据计算与分析的数据湖等多种场景。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档