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 项目,一起构建更完善的权限管理体系!

相关推荐
answerball2 小时前
🔥 Vue3响应式源码深度解剖:从Proxy魔法到依赖收集,手把手教你造轮子!🚀
前端·响应式设计·响应式编程
Slow菜鸟3 小时前
ES5 vs ES6:JavaScript 演进之路
前端·javascript·es6
小冯的编程学习之路3 小时前
【前端基础】:HTML
前端·css·前端框架·html·postman
科科是我嗷~5 小时前
【uniapp】textarea maxlength字数计算不准确的问题
javascript·uni-app·html
懒大王95275 小时前
uniapp+Vue3 组件之间的传值方法
前端·javascript·uni-app
烛阴6 小时前
秒懂 JSON:JavaScript JSON 方法详解,让你轻松驾驭数据交互!
前端·javascript
拉不动的猪6 小时前
刷刷题31(vue实际项目问题)
前端·javascript·面试
zeijiershuai6 小时前
Ajax-入门、axios请求方式、async、await、Vue生命周期
前端·javascript·ajax
恋猫de小郭6 小时前
Flutter 小技巧之通过 MediaQuery 优化 App 性能
android·前端·flutter