Vue中利用位运算计算权限

1,533 阅读3分钟

说在前面

日常的系统中,经常需要给用户做权限控制。一般的做法是,为每种权限分配一个id,然后把权限组合成一个数组。每次需要判断权限,组合权限的时候都需要进行数组操作。

最近刷视频,看vue3,其中有提到在Vue3中,模板静态化分析的时候会给模板用数字标记类型。然后再使用的时候是通过位运算来判断标记类型需要做哪些操作。显然位运算会比数组操作速度来的更快。当时看到弹幕一片懵逼,好像这种权限控制方式有点绕。

位运算如何实现权限管理

2的N次方定义权限

定义权限需要是2的N次方。

可以直接写

var ADD = 1; // 增加权限
var UPD = 2; // 修改权限
var SEL = 4; // 查找权限
var DEL = 8; // 删除权限

也可以像vue里面一样通过通过 << 零填充左位移符号来定义。因为在二进制中,1后面补0,结果就是2的N次方。

export const emun PatchFlags {
    TETX = 1,
    CLASS = 1 << 1,
    STYPE = 1 << 2,
    PROPS = 1 << 3,
    FULL_PROPS = 1 << 4,
    ...
}

需要这样做的原理是,有且只有一个1的二进制数表示一种权限。如果有多个1那么这个二进制表示多种权限。每一位表示一种权限。

0001 增加权限
0010 修改权限
0100 查找权限
1000 删除权限

例如 “|” OR 添加权限

通过二进制OR 运算来组合两个权限。

var A = ADD | UPD | SEL | DEL; // A 拥有增删改查权限

进行OR操作(OR操作只要有一个是1,那么结果就是1)

 0001
 0010
 0100
 1000
=1111

1111就表示了增删改查权限

利用 “&” AND 和 “~” 取反 删除权限

var A = ADD | UPD | SEL | DEL; // A 拥有增删改查权限
A = A & ~DEL; // A删除了DEL权限

DEL进行~取反操作

     1000  DEL
= (1)1000  ~DEL

然后进行 & AND 操作

     1111  增删改查
  (1)1000  ~DEL
=    0111 新的权限已经没有了 DEL权限了。

判断权限

判断一个权限组是否包含某个权限,直接进行 & AND操作就好了。如果操作结果大于1,就表示拥有权限。

var A = ADD | UPD | SEL | DEL; // A 拥有增删改查权限
A = A & ~DEL; // A删除了DEL权限

console.log((A & DEL)>0) // false
console.log((A & ADD)>0) // true

结果是0 自动转换位false

 0111  A权限组
 1000 DEL
=0000 AND操作,只要有一位是0,结果就是0

结果是1 自动转换位true

 0111  A权限组
 0001 ADD权限
=0001

最后,因为每一种权限都占了一个二进制位。所以这种方式并不适合超大权限集合。因为二进制位数是有限的(32位?所以最多支持32个权限···)。