vue中基于“js位运算”的实现权限控制!

我们前端在用vue做权限的时候,大部分情况可以用非常粗旷的方式,直接在html中写v-if。
在遇到比较复杂的情况时候时候,也会用1、2、3、4这种数字,每个数字来对应一种角色种方式。
但如果现在有100个按钮,需要进行权限组合还需要灵活的配置,那这种1、2、3、4方式就不灵了。
综上,我们来说一种基于“js位运算”的权限管理实现思路。

首先我们要知道什么是位运算,我们来举个例子说明一下原理:

  • 首先,我们声明三个二进制数
let a = 0b00000
let b = 0b00001
let c = 0b00100
  • 声明完毕,假设a b各对应一个权限,那我们怎么才能把 a和b 组合起来呢?没错 那就是"或运算"!只要其中一个是1,那么就会返回1。
// a与b组合
0b00000
0b00001
-----------------------进行或运算 “|”
0b00001

// 我们在组合一条c
0b00001
0b00100
-----------------------或运算 “|”
0b00101

这样我们就得到了一个新的二进制数“0b00101”

  • 再说说怎么判断权限,我们现在已经将a、b、c组合,我们可以带入实际工作,把a看作我们最初的没有权限,在和b、c结合后,新增了两条权限。 那么接下来,我们就要进行判断,怎么才能验证是否有这条权限呢?

话不多说,跟紧我,我们现在要验证是否有a权限!

0b00101  ---这个是刚才组合后的结果 ,
0b00001  ---这个是a权限
-------------------与运算  “ & ”
0b00001  ---这个也是a权限

我们看一下上面这个竖式,只要进行与运算(上下都为1才是1)。也就是说,进行下面的判断,返回一个布尔值,我们的目的就达成了!

console.log(a === my & a)

>>> true
  • 那么,怎么才能删除一个权限呢?异或运算(相同为0,不同的为1)
0b00101  ---这个是刚才组合后的结果 ,
0b00001  ---这个是a权限
-------------------异或运算  “ ^ ”
0b00100  ---这个也是a权限

你看,原理是不是很简单。

我们来创建一个类,来实现这个功能,相信大家都比我做得好,具体不再赘述。
import lodash from 'lodash'
export class MyPermission {
  /**
   * 权限,类
   * @param {number} currentPageAuth 例如:0b0000111 该地之下的用户的权限值
   * @param {string:array} currentPagePath 例如:'setting.userPermission' 用于当前页面的权限表的地址
   */
  constructor (currentPageAuth = 0b0, currentPagePath = '') {
    // 权限表: type:Object
    this.permissionDictionary = MyPermission.permissionDictionary()
    // 用户的权限(当前页):number
    this.currentPageAuth = currentPageAuth

    // 当前页的权限路径例如:
    this.currentPagePath = currentPagePath
  }

  // 以'.'的方式找到对象内部的值,如无必要,应使用lodash.get方法
  static ObjFindBySpot (key, obj) {
    try {
      // 用户输入类似‘admin.pageVisible’,以点分割
      const arr = key.split('.')
      // 传入字典,将会在此字典内处寻找值
      let val = obj
      // 递归查找
      const findRecursion = (arr, index) => {
        if (index < arr.length) {
          val = val[arr[index]]
          findRecursion(arr, (index += 1))
        }
      }
      findRecursion(arr, 0)
      return val
    } catch (error) {
      return undefined
    }
  }

  //
  /**
   * 判断权限
   * @param {array} fullKeyArray 后带上.value
   * @returns {Boolean} 判断是否有当前权限
   */
  judgmentAuth (fullKeyArray) {
    return lodash.get(this.permissionDictionary, fullKeyArray) === (this.currentPageAuth & lodash.get(this.permissionDictionary, fullKeyArray))
  }

  // 组合权限
  combination (keyAddress) {
    keyAddress.push('value')
    this.currentPageAuth = this.currentPageAuth | lodash.get(this.permissionDictionary, keyAddress)
    this.sayMyAuth()
    return this.currentPageAuth
  }

  /**
   * 删除权限
   * @param {array} keyAddress 不需要带.value
   * @returns {number} 返回删除后的值
   */
  del (keyAddress) {
    // keyAddress = `${this.currentPagePath}.${keyAddress}.value`
    keyAddress.push('value')
    // 异或会导致重复操作
    if (this.judgmentAuth(keyAddress)) {
      this.currentPageAuth = this.currentPageAuth ^ lodash.get(this.permissionDictionary, keyAddress)
    }
    this.sayMyAuth()
    return this.currentPageAuth
  }

  // 返回currentPageAuth:number
  sayMyAuth () {
    console.log(this.currentPageAuth.toString(2))
    return this.currentPageAuth
  }

  //
  /**
   * 当前页的权限信息,每个页面可以调用该方法获取所有的权限信息
   * @returns {object} 新增了isShow字段,用户可以使用该字段进行判断是否展示
   */
  showMeCurrentPageDetail () {
    const detail = lodash.cloneDeep(lodash.get(this.permissionDictionary, this.currentPagePath))
    Object.keys(detail).forEach((key) => {
      Reflect.deleteProperty(detail[key], 'value')
      // 添加isShow字段,业务组件调用此方法可以使用isShow来控制组件是否有该部分权限。
      detail[key].isShow = this.judgmentAuth(`${this.currentPagePath}.${key}.value`)
    })

    return detail
  }

  /**
   * 用户初始化字典
   * @returns {object} 用于初始化用户权限字典
   */
  userPermissionTemplate () {
    const dic = JSON.parse(JSON.stringify(this.permissionDictionary))
    // 创建初始化字典
    Object.keys(dic).forEach((key1) => {
      Object.keys(dic[key1]).forEach((key2) => {
        dic[key1][key2] = 0b0
      })
    })
    return dic
  }

  help () {
    console.log(
      `
      /* 调用示例
      * const my = new MyPermission(0b0000111, 'setting.userPermission')
      * my.judgmentAuth('_create')
      * my.combination('_create')
      * my.del('_create')
      * my.sayMyAuth()
      * my.showMeCurrentPageDetail()
      * MyPermission.ObjFindBySpot('admin._create)
     */
      `

    )
  }

  /**
   * 权限表
   * 层级数应为“三级”,用户的权限表第二级后为数字
   * 最后一级的应为 _visible:{ value:0b000001,label:'-可见意否' }
   * @returns object
   *
   */
  static permissionDictionary () {
    return {
      // 保密控制台
      secruty: {
        // 侧边标签组权限
        group: {
          // 侧边标签组整体是否可见
          _visible: { value: 0b001, label: '保密控制台组-可见' }
        },
        securityConsole: {
          // 页面是否可见
          _visible: { value: 0b00000001, label: '控制台-可见' },
          // 是否可以增删改查
          _create: { value: 0b00000010, label: '控制台-创建' },
          _delete: { value: 0b00000100, label: '控制台-删除' },
          _update: { value: 0b00001000, label: '控制台-更新' },
          _search: { value: 0b00010000, label: '控制台-查找' }
        },
       
      // 倒计时
      countDown: {
        group: {
          _visible: { value: 0b001, label: '倒计时组-可见' }
        },
        countDownConsole: {
          _visible: { value: 0b00000001, label: '控制台-可见' }
        }
      }
    }
  }
}




最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 214,444评论 6 496
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,421评论 3 389
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 160,036评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,363评论 1 288
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,460评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,502评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,511评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,280评论 0 270
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,736评论 1 307
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,014评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,190评论 1 342
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,848评论 5 338
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,531评论 3 322
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,159评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,411评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,067评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,078评论 2 352

推荐阅读更多精彩内容

  • 前言 Google Play应用市场对于应用的targetSdkVersion有了更为严格的要求。从 2018 年...
    申国骏阅读 64,048评论 14 98
  • 《来,我们说说孤独》 1·他们都在写孤独 一个诗人 如果 不说说 内心的孤独 不将孤独 写进诗里 是不是很掉价呢 ...
    听太阳升起阅读 4,375评论 1 7
  • 自幼贫民窟长大的女子,侥幸多念了两本书,枉以为可以与人平起平坐。可是人生从来都是接力赛,我们却天真的当成了百米冲刺...
    Leeanran阅读 5,766评论 1 5
  • 云舒老师,姓甚名谁,男的女的,多大岁数,这些我全然不知。之所以要写写云舒老师,完全是因为他写的文章,如一个巨大的磁...
    数豆者m阅读 2,346评论 6 9
  • """1.个性化消息: 将用户的姓名存到一个变量中,并向该用户显示一条消息。显示的消息应非常简单,如“Hello ...
    她即我命阅读 2,882评论 0 5