Vue3.5 企業級管理系統實戰(二十):角色菜單

本篇聚焦于角色菜單權限分配功能的實現,圍繞“給角色賦予菜單權限”這一核心場景,從接口設計、組件封裝到頁面集成展開完整技術方案的闡述。主要內容包括:

1. 角色權限接口開發:定義獲取角色權限、分配權限等接口,規范數據交互格式;

2. 權限分配組件封裝:實現基于樹形結構的可視化權限配置組件,支持全選、父子節點聯動控制等功能;

3. 角色管理頁面集成:新增“菜單權限”操作按鈕,通過組件化方式關聯權限分配邏輯。?

?1 角色權限 api

在 src/api/roleAccess.ts 中添加角色權限相關 api,代碼如下:

//src/api/roleAccess.ts 
import service from "./config/request";
import type { ApiResponse } from "./type";export interface IRoleAccess {id: number;access_id: number;role_id: number;
}export type IRoleAccessList = IRoleAccess[];// 獲取角色對應權限
export const getRoleAccess = (id: number
): Promise<ApiResponse<IRoleAccessList>> => {return service.get(`/role_access/${id}`);
};// 給角色分配權限
export const allocRoleAccess = (id: number,data: number[]
): Promise<ApiResponse> => {return service.post(`/role_access/${id}`, {access: data});
};// 獲取角色對應權限
export const getRoleAccessByRoles = (roles: number[]
): Promise<ApiResponse<any>> => {return service.post(`/role_access/role/access`, {roles});
};

2 封裝 RoleMenu 組件

在?/src/views/system/role/components/roleMenu.vue 中封裝角色菜單分配組件,代碼如下:

//src/views/system/role/components/roleMenu.vue 
<template><el-dialog v-model="dialogVisible"><!-- 權限樹組件,展示菜單結構并支持勾選 --><el-tree:data="treeData"show-checkbox:props="defaultProps":default-expand-all="true"highlight-currentref="menuTree"node-key="id":check-strictly="checkStrictly"></el-tree><template #footer><el-button type="primary" @click="handleCheckAll">全部選擇</el-button><el-button type="warning" @click="handleSubmit">確認分配</el-button></template></el-dialog>
</template><script lang="ts" setup>
import type { IRole } from "@/api/role";
import { useMenuStore } from "@/stores/menu";
import type { PropType } from "vue";
import { ElTree } from "element-plus";
import Node from "element-plus/es/components/tree/src/model/node.mjs";
import { allocRoleAccess, getRoleAccess } from "@/api/roleAccess";
import { useReloadPage } from "@/hooks/useReloadPage";// 是否父子節點關聯(true:不關聯,false:關聯)
const checkStrictly = ref(false);
const { reloadPage } = useReloadPage();
const store = useMenuStore();
// 從菜單存儲獲取樹形菜單數據
const treeData = computed(() => store.state.menuTreeData);// 生命周期鉤子:組件掛載后獲取所有菜單數據
onMounted(() => {store.getAllMenuList();
});// 樹組件配置項,指定子節點和標簽字段
const defaultProps = {children: "children",label: "title"
};// 樹組件實例類型和引用
type ElTreeInstance = InstanceType<typeof ElTree>;
const menuTree = ref<ElTreeInstance | null>(null);// 全選狀態標識
const isCheckAll = ref(false);/*** 全選/取消全選處理函數*/
const handleCheckAll = () => {if (!isCheckAll.value) {// 設置所有節點為選中狀態menuTree.value?.setCheckedNodes(treeData.value as unknown as Node[], false);} else {// 取消所有選中狀態menuTree.value?.setCheckedNodes([], false);}isCheckAll.value = !isCheckAll.value;
};const { proxy } = getCurrentInstance()!;/*** 提交權限分配處理函數*/
const handleSubmit = async () => {const tree = menuTree.value!;// 獲取所有選中的節點IDconst keys = tree.getCheckedKeys(false);// 獲取半選中的節點ID(部分子節點被選中)const halfKeys = tree.getHalfCheckedKeys();const selectKeys = [...keys, ...halfKeys];// 調用API分配權限const res = await allocRoleAccess(role.id, selectKeys as number[]);if (res.code === 0) {proxy?.$message.success("權限分配成功");reloadPage(); // 刷新頁面}
};// 定義組件接收的props
const { role, modelValue } = defineProps({role: {type: Object as PropType<IRole>,required: true},modelValue: {type: Boolean,default: false}
});// 對話框顯示狀態
const dialogVisible = ref(modelValue);
// 定義自定義事件
const emit = defineEmits(["update:modelValue"]);// 監聽對話框顯示狀態變化,觸發自定義事件
watch(() => dialogVisible.value,(newValue) => {emit("update:modelValue", newValue);}
);/*** 獲取角色已分配的權限列表*/
const getRoleAccessList = async () => {checkStrictly.value = true; // 臨時解除父子節點關聯,避免聯動問題const res = await getRoleAccess(role.id);if (res.code === 0) {const access = res.data.map((item) => item.access_id);// 設置已選中的權限節點menuTree.value?.setCheckedKeys(access);// 異步恢復父子節點關聯setTimeout(() => {checkStrictly.value = false;}, 0);}
};// 生命周期鉤子:組件掛載后獲取角色權限
onMounted(() => {getRoleAccessList();
});
</script>

3 修改角色管理頁面

修改 src/views/system/role/index.vue,添加角色菜單權限,如圖所示:

代碼如下:

//src/views/system/role/index.vue
<template><div p-30px><h2>角色管理</h2><el-button @click="hanleAddRole">角色添加</el-button><el-table :data="roles" style="width: 100%"><el-table-column prop="id" label="角色id" width="180" /><el-table-column prop="name" label="角色名稱" width="180" /><el-table-column prop="description" label="描述" /><el-table-columnprop="is_default"label=" 默認角色":formatter="formatter"/><el-table-column label="操作" fixed="right"><template #default="scope"><el-button link @click="handleRoleMenu(scope.row)">菜單權限</el-button><el-button link @click="handleEditRole(scope.row)">編輯</el-button><el-button link @click="handleRemove(scope.row)">刪除</el-button></template></el-table-column></el-table><el-pagination:page-sizes="[1, 5, 10, 20]"layout="prev, pager, next, sizes, total":total="count":page-size="pageSize"@size-change="handleSizeChange"@current-change="handleCurrentChange"/><!-- 右側面板組件,使用 v-model 綁定 visible 控制顯示隱藏,設置標題 --><right-panel v-model="visible" :title="panelTitle"><!-- 角色編輯組件,傳遞編輯類型和編輯數據,監聽 submit 事件 --><editor-role:type="editType":data="editData"@submit="handleSubmit"></editor-role></right-panel><role-menu:role="roleData"v-model="roleMenuVisible"v-if="roleMenuVisible && roleData"></role-menu></div>
</template><script lang="ts" setup>
import type { IRole } from "@/api/role";
import { useRoleStore } from "@/stores/role";
import { useRoleHelpers } from "./roleHelpers";
import { ref, toRefs, watchEffect } from "vue";const roleData = ref<IRole | null>(null);
const roleMenuVisible = ref(false);
const handleRoleMenu = (row: IRole) => {roleMenuVisible.value = true;roleData.value = row;
};// 獲取角色狀態管理倉庫實例
const store = useRoleStore();
// 當前頁碼,初始為 0
const pageNum = ref(0);
// 每頁顯示的記錄數,初始為 10
const pageSize = ref(10);// 從 useRoleHelpers 組合式函數中解構出所需的方法和狀態
const {handleSubmit,handleRemove,handleEditRole,hanleAddRole,panelTitle,editType,visible,editData
} = useRoleHelpers({ pageNum, pageSize });// 將倉庫狀態中的 count 和 roles 轉換為響應式引用
const { count, roles } = toRefs(store.state);// 監聽 pageNum 和 pageSize 的變化,當變化時重新獲取角色數據
watchEffect(() => {store.getRoles({ pageNum: pageNum.value, pageSize: pageSize.value, flag: 0 });
});// 處理每頁顯示記錄數改變的方法
const handleSizeChange = (val: number) => {pageSize.value = val;
};// 處理當前頁碼改變的方法
const handleCurrentChange = (val: number) => {pageNum.value = val - 1;
};// 格式化是否為默認角色的顯示內容
const formatter = (row: IRole) => {return row.is_default ? "是" : "否";
};
</script>

以上,就是角色菜單的相關內容。

下一篇將繼續探討 菜單權限實現,敬請期待~

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

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

相關文章

go實現釘釘三方登錄

釘釘的的官方開發文檔中只給出了java實現三方登錄的&#xff0c;我們準備用go語言來實現 實現網頁方式登錄應用&#xff08;登錄第三方網站&#xff09; - 釘釘開放平臺 首先就是按照文檔進行操作&#xff0c;備注好網站的信息 獲得應用憑證&#xff0c;我們后面會用到 之后…

一、OpenCV的基本操作

目錄 1、OpenCV的模塊 2、OpenCV的基礎操作 2.1圖像的IO操作 2.2繪制幾何圖形 2.3獲取并修改圖像中的像素點 2.4 獲取圖像的屬性 2.5圖像通道的拆分與合并 2.6色彩空間的改變 3、OpenCV的算數操作 3.1圖像的加法 3.2圖像的混合 3.3總結 1、OpenCV的模塊 2、OpenCV的基…

虛擬機配置橋接,遠程工具直接訪問

虛擬機網絡配置 前言windows下安裝linux虛擬機配置網絡1、設置虛擬機網絡模式&#xff1a;橋接模式2、配置網絡參數1、查看本機電腦連接的網絡情況2、打開虛擬機&#xff0c;編輯配置文件3、編輯虛擬網絡 3、測試連通性 前言 好不容易裝上了虛擬機&#xff0c;輸入命令時又發現…

RabbitMQ 概述與安裝

MQ 作用與介紹 MQ 是什么 MQ (message queue),從字面意思看是一個隊列, FIFO 先進先出,只不過里面存放的內容是 消息 消息 可以比較簡單,比如只包含 文本字符串,JSON 等;也可以很復雜,比如 內嵌對象 等 MQ 多用于分布式系統之間進行通信 系統之間的調用通常有兩種方式: 1…

如何在Vue中實現延遲刷新列表:以Element UI的el-switch為例

如何在Vue中實現延遲刷新列表&#xff1a;以Element UI的el-switch為例 在開發過程中&#xff0c;我們經常需要根據用戶操作或接口響應結果來更新頁面數據。本文將以Element UI中的el-switch組件為例&#xff0c;介紹如何在狀態切換后延遲1秒鐘再調用刷新列表的方法&#xff0…

CSS2相關知識點

CSS2相關知識點 CSS的編寫位置樣式種類樣式表的優先級 CSS選擇器CSS基本選擇器通配選擇器元素選擇器類選擇器ID選擇器 復合選擇器HTML元素間的關系交集選擇器并集選擇器后代選擇器子代選擇器兄弟選擇器屬性選擇器偽類選擇器偽元素選擇器 顏色的表示表示方式一&#xff1a;顏色名…

centos yum源,docker源

yum源repo文件&#xff1a; wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repodocker源repo文件&#xff1a; yum-config-manager --add-repo http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo安裝docker和docker c…

深入探索AI模型工程:算法三大門派與監督學習的魅力

在當今人工智能蓬勃發展的時代&#xff0c;AI系統正逐漸滲透到我們生活的方方面面。從智能語音助手到自動駕駛汽車&#xff0c;從醫療影像診斷到金融風險預測&#xff0c;AI的應用場景無處不在。然而&#xff0c;構建一個高效、可靠的AI系統并非易事&#xff0c;它需要我們從宏…

[De1CTF 2019]SSRF Me

算是我第一次正兒八經的分析python代碼了 from flask import Flask, request import socket import hashlib import urllib import sys import os import jsonreload(sys) sys.setdefaultencoding(latin1)app Flask(__name__) # 創建一個Flask應用實例 secret_key os.ura…

Halcon 圖像預處理②

非線性圖像分段變化&#xff1a; 先窗體打開圖片 對數非線性變化&#xff1a; 結果圖像的亮度/對比度顯著增加 log_image(Image,LogImag1,e) 參數1&#xff1a;輸入圖像 參數2&#xff1a; 輸出圖像 參數3&#xff1a;底數 log_image(Image,LogImage2,0.1) 圖像結果亮度和…

云原生安全之網絡IP協議:從基礎到實踐指南

&#x1f525;「炎碼工坊」技術彈藥已裝填&#xff01; 點擊關注 → 解鎖工業級干貨【工具實測|項目避坑|源碼燃燒指南】 一、基礎概念 IP協議&#xff08;Internet Protocol&#xff09;是互聯網通信的核心協議族之一&#xff0c;負責在設備間傳遞數據包。其核心特性包括&…

QML學習08Text

Text 1、顏色&#xff08;color&#xff09;2、獲取寬度和高度&#xff08;contentWidth、contentHeight&#xff09;3、字體格式&#xff08;font&#xff09;4、文本樣式&#xff08;textFormat&#xff09;5、超鏈接 1、顏色&#xff08;color&#xff09; //顏色Text {colo…

Python網絡編程深度解析

目錄 一、網絡編程概述 二、TCP與UDP協議詳解 1.TCP協議&#xff1a;可靠傳輸的基石 2.UDP協議&#xff1a;高效但不可靠的傳輸 3. TCP與UDP對比 三、Socket編程模型 1. Socket基礎 2.TCP服務器實現詳解 3. UDP服務器實現詳解 四、進階應用&#xff1a;簡易聊天程序 …

ElasticSearch導讀

ElasticSearch 簡介&#xff1a;ElasticSearch簡稱ES是一個開源的分布式搜素和數據分析引擎。是使用Java開發并且是當前最流行的開源的企業級搜索引擎&#xff0c;能夠達到近實時搜索&#xff0c;它專門設計用于處理大規模的文本數據和實現高性能的全文搜索。它基于 Apache Luc…

【后端高階面經:數據庫篇】18、分布式事務:如何在分庫分表中實現高性能與一致性?

一、分布式事務核心挑戰:分庫分表下的一致性困境 在分布式系統架構中,分庫分表通過將數據分散存儲提升了擴展性和性能,但卻打破了傳統單庫事務的邊界,使得分布式事務成為保障數據一致性的核心難題。其挑戰主要體現在以下三方面: 1.1 ACID特性的分布式撕裂 原子性(Atomi…

Tailwind css實戰,基于Kooboo構建AI對話框頁面(一)

在當今數字化時代&#xff0c;AI 助手已成為網站和應用不可或缺的一部分。本文將帶你一步步使用 Tailwind CSS 和 Kooboo 構建一個現代化的 AI 對話界面框。 一、選擇 Kooboo平臺 的核心優勢 智能提示&#xff1a;在輸入 class 屬性時&#xff0c;會自動觸發 Tailwind CSS 規則…

python學習day2:進制+碼制+邏輯運算符

進制 Python 中的進制表示與轉換 進制的基本概念 二進制、八進制、十進制、十六進制的定義與特點不同進制在計算機科學中的應用場景 Python 中的進制表示 二進制表示&#xff1a;使用 0b 前綴八進制表示&#xff1a;使用 0o 前綴十六進制表示&#xff1a;使用 0x 前綴示例…

ROS2學習(11)------ROS2通信接口

操作系統&#xff1a;ubuntu22.04 IDE:Visual Studio Code 編程語言&#xff1a;C11 ROS版本&#xff1a;2 ROS 2 提供了多種通信接口&#xff0c;用于節點之間的數據交換。這些接口主要包括話題&#xff08;Topics&#xff09;、服務&#xff08;Services&#xff09;、動作&…

STM32G0xx基于串口(UART)Ymodem協議實現OTA升級包括Bootloader、上位機、應用程序

STM32G0xx基于串口Ymodem協議實現OTA升級包括Bootloader、上位機、應用程序 例程說明一、串口相關的底層配置二、OTA相關的應用層三、Flash相關的操作四、Flash存儲參數相關五、核心部分Ymodem相關六、其他宏配置七、主函數八、使用Python合并文件九、測試結果有疑問歡迎加交流…

Jenkins實踐(6):配置“構建歷史的顯示名稱,加上包名等信息“

Jenkins實踐(6):配置“構建歷史的顯示名稱,加上包名等信息“ 版本:Jenkins 4.262.2 需求:想要在構建歷史中展示,本次運行的是哪個版本或哪個包 操作步驟: 1、先安裝插件Build Name and Description Setter 2、Set Build Name 3、構建歷史處查看展示 插件特性說明 安裝依賴…