Vue 3 中搭建菜单权限配置界面的详细指南

在现代 Web 应用开发中,菜单权限配置是一个至关重要的功能,它确保不同角色的用户能够访问特定的功能模块。Vue 3 作为一款流行的 JavaScript 框架,为我们提供了高效且灵活的方式来构建这样的界面。本文将通过实际代码示例,详细讲解如何在 Vue 3 中搭建一个菜单权限配置界面。

一、界面基础结构搭建

我们使用 Element Plus 库来构建用户界面。在<template>部分,我们创建了一个el-dialog组件,作为菜单权限配置的弹窗。

html 复制代码
<el-dialog

title="菜单权限"

width="1000"

center

destroy-on-close

@open="dialogOpen"

>

<div>

<div>角色名称:jiaberr</div>

<div>

<text>菜单权限:</text>

<el-checkbox v-model="expandAll" @change="handleExpandAllChange">

展开/折叠

</el-checkbox>

<el-checkbox v-model="checkAll" @change="handleCheckAllChange">

全选/全不选

</el-checkbox>

<el-checkbox v-model="checkStrictly"> 父子联动 </el-checkbox>

</div>

<div class="w-p-100 containner">

<el-tree

ref="treeRef"

:props="treeProps"

:data="menudatas"

show-checkbox

node-key="id"

:check-strictly="!checkStrictly"

:default-expanded-keys="expandedKeys"

:default-checked-keys="checkedData"

/>

</div>

</div>

<template #footer>

<div class="dialog-footer">

<el-button @click="close">取消</el-button>

<el-button type="primary" @click="handleSubmit"> 确定 </el-button>

</div>

</template>

</el-dialog>

在这段代码中,el-dialog包含了角色名称显示、菜单权限操作按钮(展开 / 折叠、全选 / 全不选、父子联动)以及一个el-tree组件用于展示菜单树结构。el-tree通过绑定menudatas数据来渲染菜单节点,并通过各种属性配置其行为,如check-strictly控制是否严格父子联动,default-expanded-keys和default-checked-keys分别设置默认展开和选中的节点。

二、数据与功能实现

在<script setup>部分,我们定义了各种数据和函数来实现菜单权限配置的核心功能。

1. 引入依赖和定义数据

javascript 复制代码
import { ref, provide, watchEffect, onMounted } from "vue";

import { roleMenusPermissionData } from "./simulatedData.js";

import { getDynamicRoutes } from "@/utils/getData.js";

const props = defineProps({

roleId: {

Type: Number,

required: true,

},

});

const treeProps = {

label: (data) => data.meta.title,

};

// 获取菜单树结构

const menudatas = ref([]);

const checkAll = ref(false); // 全选

const expandAll = ref(true); // 展开

const checkStrictly = ref(true); // 父子联动

我们引入了 Vue 的响应式数据函数ref,以及用于依赖注入的provide等。通过defineProps接收父组件传递的roleId,这在实际应用中可用于根据不同角色加载不同的菜单权限数据。treeProps定义了如何显示el-tree节点的标签,即通过data.meta.title。menudatas用于存储菜单树的数据,checkAll、expandAll和checkStrictly分别控制全选、展开和父子联动的状态。

2. 数据加载与监听

javascript 复制代码
watchEffect(() => {

// 仅模拟页面效果使用,根据不同id获取不同的菜单权限

if (props.roleId == 1) {

} else {

}

});

onMounted(() => {

getDynamicRoutes().then((res) => {

menudatas.value = res;

});

});

watchEffect函数用于监听props.roleId的变化,这里只是简单的模拟,实际应用中可以根据不同的roleId从后端获取相应的菜单权限数据。onMounted钩子函数在组件挂载后执行,通过调用getDynamicRoutes函数从后端获取动态路由数据,并将其赋值给menudatas,从而渲染菜单树。

3. 全选 / 全不选功能实现

javascript 复制代码
const handleCheckAllChange = (val) => {

const permissionIds = extractPermissionIds(menudatas.value);

if (val) {

treeRef.value.setCheckedKeys(permissionIds);

} else {

treeRef.value.setCheckedKeys([]);

}

};

handleCheckAllChange函数在全选 / 全不选复选框状态改变时触发。它首先通过extractPermissionIds函数获取所有菜单节点的id,然后根据复选框的状态,使用treeRef.value.setCheckedKeys方法设置el-tree的选中节点。

4. 展开 / 折叠功能实现

javascript 复制代码
const expandedKeys = ref([]);

const treeRef = ref(null);

//展开、折叠

const handleExpandAllChange = (value) => {

expandAll.value = value;

let nodes = treeRef.value.store._getAllNodes();

if (expandAll.value) {

nodes.forEach((item) => {

item.expanded = expandedKeys.value;

});

} else {

nodes.forEach((item) => {

item.expanded =!expandedKeys.value;

});

}

};

handleExpandAllChange函数用于处理展开 / 折叠操作。它通过treeRef.value.store._getAllNodes()获取el-tree的所有节点,然后根据expandAll的值,遍历节点并设置其expanded属性,从而实现展开或折叠所有节点的效果。

5. 父子联动功能实现

javascript 复制代码
// 父子联动

const handleCheckStrictlyChange = (val) => {

// 因为后端返回的id包括了父节点的id,父子联动时如果有父节点则默认会将所有子节点勾选,为了避免这种情况,所有需要把后台返回的父节点id筛出去

if (val) {

treeRef.value.setCheckedKeys(extractChildPermissionIds(menudatas.value));

}

};

handleCheckStrictlyChange函数在父子联动复选框状态改变时触发。当开启父子联动时,它通过extractChildPermissionIds函数获取所有子菜单节点的id,并使用treeRef.value.setCheckedKeys方法设置el-tree的选中节点,以确保在父子联动模式下,只勾选子菜单节点,避免因父节点勾选而自动勾选所有子节点的问题。

6. 提交功能实现

javascript 复制代码
// 提交

const handleSubmit = () => {

// 将选中的id数组上传至后台接口,根据后端的要求,如果需要穿父节点,那checkedKeys和halfCheckedKeys都需要上传

const checkedKeys = treeRef.value.getCheckedKeys()

const halfCheckedKeys = treeRef.value.getHalfCheckedKeys()

console.log(

treeRef.value.getCheckedKeys(),

treeRef.value.getHalfCheckedKeys()

);

emits("close");

};

handleSubmit函数在用户点击确定按钮时触发。它通过treeRef.value.getCheckedKeys()和treeRef.value.getHalfCheckedKeys()获取已选中和半选中的节点id,然后可以将这些id数组上传至后端接口,完成菜单权限的配置更新。最后,通过emits("close")关闭弹窗。

三、样式调整

在<style lang="scss" scoped>部分,我们为el-tree的容器添加了一个简单的边框样式。

css 复制代码
.containner {

border: 1px solid #d3d3d3;

}

通过这种方式,我们可以根据实际需求对菜单权限配置界面进行样式定制,提升用户体验。

通过以上步骤,我们成功地在 Vue 3 中搭建了一个功能齐全的菜单权限配置界面。这个界面不仅能够展示菜单树结构,还提供了全选 / 全不选、展开 / 折叠、父子联动以及提交配置等功能,满足了实际项目中菜单权限管理的需求。

完整代码实现请参考开源项目:vue3-pc-template

欢迎 Star 和 Fork 项目,一起构建更完善的权限管理体系!

相关推荐
恋猫de小郭17 小时前
Flutter Zero 是什么?它的出现有什么意义?为什么你需要了解下?
android·前端·flutter
崔庆才丨静觅1 天前
hCaptcha 验证码图像识别 API 对接教程
前端
passerby60611 天前
完成前端时间处理的另一块版图
前端·github·web components
掘了1 天前
「2025 年终总结」在所有失去的人中,我最怀念我自己
前端·后端·年终总结
崔庆才丨静觅1 天前
实用免费的 Short URL 短链接 API 对接说明
前端
崔庆才丨静觅1 天前
5分钟快速搭建 AI 平台并用它赚钱!
前端
崔庆才丨静觅1 天前
比官方便宜一半以上!Midjourney API 申请及使用
前端
Moment1 天前
富文本编辑器在 AI 时代为什么这么受欢迎
前端·javascript·后端
崔庆才丨静觅1 天前
刷屏全网的“nano-banana”API接入指南!0.1元/张量产高清创意图,开发者必藏
前端
剪刀石头布啊1 天前
jwt介绍
前端