位運算在權限授權中的應用及Vue3實踐

在現代前端應用中,權限管理是一個至關重要的功能模塊。隨著應用復雜度的提示功能,權限細粒度越來越精細,如何高效地管理和判斷權限成為前端開發的一大挑戰。位運算作為一種高效的運算方式,在權限管理領域有著獨特的優勢。本文將詳細介紹位運算在權限授權中的應用,并結合Vue3框架展示具體實現。

位運算與權限管理的天然契合

權限管理的核心需求可以概括為:表示權限集合、添加權限、移除權限和驗證權限。這恰好與位運算的特性高度匹配。

位運算的優勢:

  • 高效性:直接操作二進制,性能遠優于數組或對象操作
  • 簡潔性:用一個整數即可表示多個權限的數組狀態
  • 擴展性:輕松添加新權限類型,不影響已有邏輯
  • 內存友好:一個32位整數可表示32種不同權限,64位整數則可表示64種

核心位運算原理

在權限管理中,我們主要使用以下四種位運算:

  1. 按位或(|=)添加權限
userPermissions != permission;
  1. 按位與(&)驗證權限
const hasPermission = (userPermission & permission) !== 0;
  1. 按位與非(&=~)移除權限
userPermissions &= ~permission;
  1. 按位異或(^=)切換權限
userPermissions ^= permission;

權限設計模式

權限定義

首先為每種權限定義一個唯一的標識符,采用2的冪次方形式:

// src/enums/permission.ts
export enum Permission {// 基礎權限VIEW = 1 << 0, // 1 (二進制:0001)- 查看權限EDIT = 1 << 1, // 2 (二進制:0010)- 編輯權限DELETE = 1 << 2, // 4 (二進制:0100)- 刪除權限CREATE = 1 << 3, // 8 (二進制:1000) - 創建權限// 高級權限APPROVE = 1 << 4, // 16 - 審批權限EXPORT = 1 << 5, // 32 - 導出權限IMPORT = 1 << 6, // 64 - 導入權限// 管理員權限ADMIN = VIEW | EDIT | DELETE | CREATE | APPROVE | EXPORT | IMPORT
}// 權限描述信息
export const PermissionDesc = {[Permission.VIEW]: {name: '查看', description: '查看內容的權限'},[Permission.EDIT]: {name: '編輯', description: '編輯內容的權限'},[Permission.DELETE]: {name: '刪除', description: '刪除內容的權限'},[Permission.CREATE]: {name: '創建', description: '創建內容的權限'},[Permission.APPROVE]: {name: '審批', description: '審批內容的權限'},[Permission.EXPORT]: {name: '導出', description: '導出內容的權限'},[Permission.IMPORT]: {name: '導入', description: '導入內容的權限'},[Permission.ADMIN]: {name: '管理員', description: '擁有所有的權限'}
}

權限管理工具類

封裝一個權限管理工具類,提供權限操作的核心方法:

// src/utils/permissionManager.ts
import { Permission } fro '@enums/permissions';class PermissionManager {private permissions: number;constructor(initialPermissions: number = 0){this.permissions = initialPermissions;}/*** 添加權限* @param permission 權限值,可以是單個權限或多個權限的組合*/add(permission: Permission): void {this.permissions != permission;}/*** 移除權限* @param permission 權限值,可以是單個權限或多個權限的組合*/remove(permission: Permission): void {this.permissions &= ~permission;}/*** 檢查是否擁有指定權限* @param permission 權限值,可以是單個權限或多個權限的組合* @returns 是否擁有權限*/has(permission: Permission): boolean {return(this.permissions & permission) !== 0;}/*** 切換權限狀態* @param permission 權限值*/toggle(permission: Permission): void {this.permission ^= permission;}/*** 獲取當前所有權限值* @returns 權限值*/getValue(): number {return this.permissions;}/*** 重置權限* @param permissions 新的權限值,默認為0(無權限)*/reset(permissions: number = 0): void {this.permissions = permissions;}
}export default PermissionManager;

Vue3中的實踐應用

全局權限狀態管理

使用Pinia存儲全局權限狀態,便于在整個應用中共享和訪問:

// src/stores/permissionStore.ts
import { defineStore } from 'pinia';
import PermissionManager from '@/utils/permissionManager';
import { Permission } from '@/enums/permissions';export const usePermissionStore = defineStore('permission', {state: () => ({manager: new PermissionManager(),initialized: false}),actions: {async init() {try {// 實際項目中從接口中獲取// 這里模擬獲取權限值const permissionValue = Permission.VIEW | Permission.EDIT | Permission.CREATE;this.manager.reset(permissionValue);this.initialized = true;} catch(error){this.initialized = false;}},addPermission(permission: Permission) {this.manager.add(permission)},removePermission(permission: Permission) {this.manager.remove(permission)},hasPermission(permission: Permission): boolean{return this.manager.has(permission);},togglePermission(permission: Permission) {this.manager.toggle(permission)}}
})

權限指令

創建自定義指令,用于在模版中控制元素的顯示或操作權限:

// src/directives/permission.ts
import { DirectiveBinding } from 'vue';
import { usePermissionStore } from '@/stores/permissionStore';
import { Permission } from '@/enums/permissions';export default {mounted(el: HTMLElement, binding: DirectiveBinding){const permissionStore = usePermissionStore();const requiredPermission = binding.value as Permission;// 檢查是否有權限const hasPermission = permissionStore.hasPermission(requiredPermission);// 如果沒有權限,移除元素或禁用元素if(!hasPermission) {if(binding.modifiers.disabled) {el.disabled = true;el.classList.add('opacity-50', 'cursor-not-allowed');} else {el.parentNode?.removeChild(el);}}}
}

在main.ts中注冊指令:

// src/main.ts
import { createApp } from 'vue';
import App from './App.vue';
import permissionDirective from './directives/permission';const app = createApp(App);
app.directive('permission', permissionDirective);
app.mount('#app');

權限組件

創建一個權限檢查組件,用于包裹需要控制權限的內容:

<template><slot v-if="hasPermission"></slot><slot name="fallback" v-else></slot>
</template><script setup lang="ts">
import { defineProps, computed } from 'vue';
import { usePermissionStore } from '@/stores/permissionStore';
import { Permission } from '@/enums/permissions';const props = defineProps<{required: Permission
}>();const permissionStore = usePermissionStore();
const hasPermission = computed(()=> {return permissionStore.hasPermission(props.required)
})
</script>

在組件中使用

 <template><div class="permission-demo"><!-- 指令控制按鈕是否顯示 --><button v-permission:[Permission.EDIT]>編輯</button><!-- 無權限時禁用 --><button v-permission:[Permission.DELETE].disabled>刪除</button><!-- 使用權限組件控制區域 --><PermissionGuard :required="Permission.CREATE"><div class="create-content"><!-- 創建區域 --></div><template #fallback><div class="no-permission">沒有創建權限</div></template></PermissionGuard><!-- 權限狀態展示 --><div class="permission-status"><h3>當前權限狀態</h3><ul><li v-for="(desc, perm) in PermissionDesc" :key="perm"><div :class="'has-perm': hasPermission(perm)">{{desc.name}}: {{hasPermission(perm) ? '已擁有' : '未擁有'}}</div></li></ul><!-- 權限操作按鈕 --><div class="permission-actions"><button @click="togglePermission(Permission.DELETE)">切換刪除權限</button><button @click="togglePermission(Permission.ADMIN)">切換管理員權限</button></div></div></div>
</template>
<script setup lang="ts">
import { Permission, PermissionDesc } from '@/enums/permissions';
import { usePermissionStore } from '@/stores/permissionStore';
import PermissionGuard from '@/components/PermissionGuard.vue';const permissionStore = usePermissionStore();
// 檢查權限
const hasPermission = (perm: Permission) => {return permissionStore.hasPermission(perm)
}
// 切換權限
const togglePermission = (perm: Permission) => {permissionStore.togglePermission(perm)
}
</script><style scoped>
.has-perm {color: green;font-weight: bold;
}.no-permission {color: #999;padding: 1rem;border: 1px dashed #ccc;border-radius: 4px;
}.permission-actions {margin-top: 1rem;display: flex;gap: 0.5rem;
}button {margin: 0.5rem;padding: 0.5rem 1rem;cursor: pointer;
}button:disabled {cursor: not-allowed;
}

權限系統的擴展與優化

  1. 權限組管理:對于復雜應用,可以將權限分組管理,每組權限使用獨立的位段。
  2. 權限緩存:將用戶權限緩存到localStorage或sessionStorage中,減少重復請求。
  3. 權限驗證中間件:在路由導航時添加權限驗證,防止未授權方位。
// src/router/permissionGuard.ts
import { NavigationGuardNext, RouteLocationNormalized } from 'vue-router';
import { usePermissionStore } from '@/stores/permissionStore';
import { Permission } from '@/enums/permissions';interface RouteMeta {requiredPermission?: Permission;
}export function permissionGuard(to: RouteLocationNormalized & { meta: RouteMeta },from: RouteLocationNormalized,next: NavigationGuardNext
){const permissionStore = usePermissionStore();const requiredPermission = to.meta.requiredPermission;// 如果路由不需要權限,直接放行if(!requiredPermission) {next();return;}// 檢查是否有權限if(permissionStore.hasPermission(requiredPermission)) {next();} else {// 無權限,重定向到無權限頁面next('/no-permission')}
}

總結

位運算為前端權限管理提供了一種高效、簡潔的解決方案。通過合理設計權限體系,并結合Vue3的響應式系統、狀態管理和自定義指定,可以構建出靈活且高性能的權限管理模塊。

在實際項目中,應根據應用的復雜度和權限需求選擇合適的權限設計方案。對于中小型應用,本文介紹的位運算方案足夠應對大多數場景;對于超大型應用,可能需要結合更復雜的權限模型,但位運算依然可以作為底層的高效運動方式發揮重要作用。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/pingmian/91780.shtml
繁體地址,請注明出處:http://hk.pswp.cn/pingmian/91780.shtml
英文地址,請注明出處:http://en.pswp.cn/pingmian/91780.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

面試實戰,問題二十二,Java JDK 17 有哪些新特性,怎么回答

Java JDK 17 新特性面試回答指南 作為一名Java開發者&#xff0c;了解JDK 17的新特性是面試中的關鍵點。JDK 17&#xff08;Java SE 17&#xff09;于2021年9月發布&#xff0c;是一個長期支持&#xff08;LTS&#xff09;版本&#xff0c;引入了多項改進以提升開發效率、安全性…

【MySQL安全】什么是SQL注入,怎么避免這種攻擊:前端防護、后端orm框架、數據庫白名單

基本概念SQL注入是OWASP Top 10安全風險之一&#xff0c;它利用了應用程序對用戶輸入數據的不當處理。當應用程序直接將用戶輸入拼接到SQL查詢中而沒有進行適當的過濾或轉義時&#xff0c;就可能發生SQL注入攻擊。攻擊原理假設有一個登錄表單的SQL查詢&#xff1a;SELECT * FRO…

pyqt5顯示任務欄菜單并隱藏主窗口,環境pyqt5+vscode

環境 pyqt5vscode 環境搭建見 https://blog.csdn.net/huiaifen/article/details/125175261 新建一個QMainWindow 1 在VSCode的資源管理器中&#xff0c;右鍵選擇 PYQT:New Form&#xff0c;打開Qt Designer2 在打開的窗口中選 “Main Window”&#xff0c;然后選“創建”3 直接…

SpringBoot項目數據脫敏(自定義注解)

文章目錄前言一.配置1.脫敏類型枚舉&#xff1a;DesensitizeType2.注解&#xff1a;Desensitize3.序列化類&#xff1a;DesensitizeJsonSerializer4.工具類&#xff1a;DesensitizeUtil二、測試&#xff1a;DesensitizeTest三、效果展示總結前言 在互聯網應用中&#xff0c;用戶…

PSO-TCN-BiLSTM-MATT粒子群優化算法優化時間卷積神經網絡-雙向長短期記憶神經網絡融合多頭注意力機制多特征分類預測/故障診斷Matlab實現

基本介紹 1.Matlab實現PSO-TCN-BiLSTM-MATT粒子群算法優化時間卷積神經網絡-雙向長短期記憶神經網絡融合多頭注意力機制多特征分類預測&#xff0c;PSO-TCN-BiLSTM-Multihead-Attention&#xff1b; 多頭自注意力層 (Multihead-Self-Attention)&#xff1a;Multihead-Self-Atte…

第一篇:Linux 運維入門:虛擬機部署與基礎環境配置

目錄 一、準備工作與環境規劃 二、虛擬機網絡配置 1、虛擬網絡編輯器設置 2、系統網絡配置 3、主機名配置 三、Hosts 文件與 SSH 免密配置 配置 hosts 文件編輯/etc/hosts文件實現主機名解析&#xff1a; 分發 hosts 文件到其他節點 SSH 免密登錄配置在 zhangsan101 上…

(一)全棧(react配置/https支持/useState多組件傳遞/表單提交/React Query/axois封裝/Router)

文章目錄 項目地址 一、基礎配置 1.1 支持https 1. 安裝所需要的包 2. 配置 1.2 常用 1. 字符串拼接 二、組件 2.1 useState組件傳遞 1. App里初始化useState 2. useState和方法的傳遞 3. 接收傳遞來的狀態和方法 2.2 表單提交 1. 表單組件處理用戶輸入數據 2. App傳來的submit…

【abc417】E - A Path in A Dictionary

Problem StatementYou are given a simple connected undirected graph G with N vertices and M edges. The vertices of G are numbered vertex 1, vertex 2, …, vertex N, and the i-th (1≤i≤M) edge connects vertices Ui? and Vi?.Find the lexicographically smalle…

linux火焰圖

火焰圖簡介火焰圖是一種性能分析的可視化工具&#xff0c;它將CPU的調用棧&#xff08;Call Stack&#xff09;信息以矩形火焰的形式展現出來。Y軸&#xff1a;代表調用棧的深度&#xff08;函數A調用了函數B&#xff0c;B就疊在A上面&#xff09;。X軸&#xff1a;代表CPU的抽…

解剖 .NET 經典:從 Component 到 BackgroundWorker

1?? 背景與定位在 .NET Framework 2.0 時代&#xff0c;微軟引入了 BackgroundWorker 來解決 WinForm/WPF 場景下“耗時操作阻塞 UI 線程”的問題&#xff1b;而 Component 早在 1.0 就已存在&#xff0c;是所有可視化/非可視化設計器的“基類”。理解這兩者的源碼與機制&…

桌面端界面設計 |貨物 TMS 系統 - SaaS UI UX 設計:審美積累之境

在物流數字化的浪潮中&#xff0c;貨物 TMS 系統的 SaaS 化與 UI/UX 設計正構建著獨特的審美坐標系。這不僅是技術與功能的融合&#xff0c;更是一場關于效率美學的深度探索&#xff0c;為行業審美積累注入了鮮活的實踐樣本。SaaS 模式賦予貨物 TMS 系統輕盈而強大的特質&#…

多架構鏡像整合全攻略:在Docker中實現單一鏡像支持同時支持amd64和arm64架構

多架構支持的挑戰 &#xff1a;隨著異構計算&#xff08;如 ARM、x86、RISC-V 等&#xff09;的普及&#xff0c;開發者需要為不同硬件平臺提供對應的鏡像&#xff0c;傳統方式需維護多個版本&#xff08;如 image:v1-amd64 和 image:v1-arm64 &#xff09;&#xff0c;導致版本…

Linux730 tr:-d /-s;sort:-r,-n,-R,-o,-t,-k,-u;bash;cut:-d,-c;tee -a;uniq -c -i

回顧 sort sort [選項] 文件-u&#xff1a;唯一&#xff0c;去除重復 -r:按數字大小&#xff0c;倒序排序&#xff0c;大到小 -o:輸出文件 -n:按數字大小&#xff0c;順序排序&#xff0c;小到大 -t: -t后加分割符&#xff0c;按分割符為標準&#xff0c;進行篩選 -k:k后加數字…

力扣457:環形數組是否存在循環

力扣457:環形數組是否存在循環題目思路代碼題目 存在一個不含 0 的 環形 數組 nums &#xff0c;每個 nums[i] 都表示位于下標 i 的角色應該向前或向后移動的下標個數&#xff1a; 如果 nums[i] 是正數&#xff0c;向前&#xff08;下標遞增方向&#xff09;移動 |nums[i]| 步…

在 Elasticsearch 中落地 Learning to Rank(LTR)

1 為什么要引入 LTR&#xff1f; 常規檢索&#xff08;BM25、語義檢索、Hybrid、RRF …&#xff09;往往只能基于少量信號&#xff08;關鍵詞命中、向量相似度&#xff09;排序。 Learning-to-Rank 通過機器學習模型把多維度特征&#xff08;文檔屬性、查詢屬性、查詢-文檔相關…

Socket編程——TCP協議

文章目錄一、TCP傳輸二、相關接口三、多進程版本四、多線程版本一、TCP傳輸 TCP和UDP類似&#xff0c;但是在傳輸中TCP有輸入&#xff0c;輸出緩沖區&#xff0c;看下面的傳輸圖片 可以理解為TCP之間的數據傳輸都是依賴各自的socket&#xff0c;socket就充當傳輸的中介吧。 而…

GitHub使用小記——本地推送、外部拉取和分支重命名

GitHub 項目推送與拉取等操作使用隨記 本小記適用于個人項目或組織項目&#xff0c;涵蓋 GitHub 推送、拉取、分支管理、.gitignore 設置等常見需求。 1. 將已有本地工程推送至 GitHub 新倉庫 1.1 前提條件 本地項目結構完整&#xff0c;已準備好&#xff1b;本地已安裝 Git…

RabbitMQ 延時隊列插件安裝與使用詳解(基于 Delayed Message Plugin)

RabbitMQ 延時隊列插件安裝與使用詳解&#xff08;基于 Delayed Message Plugin&#xff09;&#x1f4cc; 一、什么是 RabbitMQ 延時隊列&#xff1f;&#x1f680; 二、安裝前準備? RabbitMQ 環境要求&#x1f527; 三、安裝延時隊列插件&#x1f9e9; 插件名稱&#xff1a;…

Vue項目使用ssh2-sftp-client實現打包自動上傳到服務器(完整教程)

告別手動拖拽上傳&#xff01;本教程將手把手教你如何通過ssh2-sftp-client實現Vue項目打包后自動上傳到服務器&#xff0c;提升部署效率300%。&#x1f680;一、需求場景與解決方案在Vue項目開發中&#xff0c;每次執行npm run build后都需要手動將dist目錄上傳到服務器&#…

《質光相濟:Three.js中3D視覺的底層交互邏輯》

在Three.js搭建的虛擬維度中,光照與材質的關系遠非技術參數的簡單疊加,當光線以數字形態穿越虛空,與物體表面相遇的瞬間,便開始書寫屬于這個世界的物理敘事——每一縷光斑的形狀、每一塊陰影的濃淡、每一寸肌理的反光,都是對現實光學規律的轉譯與重構。理解這種交互的深層…