当前位置: 首页 > news >正文

vue3+element-plus权限控制实现(el-tree父子级不关联情况处理)

文章目录

  • 前言
  • 一、遇到的交互场景
      • el-tree 中 check-strictly 属性
  • 二、处理父级的半选中以及选中交互
      • el-tree
      • check,check-change 事件
      • 编辑进来,父级的半选状态处理
  • 总结


前言

在开发后台管理系统的时候,用户的权限控制是一个常见的需求。这里需要探讨下按钮的级别的权限控制,以及实现中使用element-plus tree 组件的使用细节。


一、遇到的交互场景

基于原有的基础上实现按钮级别的权限控制,原有的如下图每一个菜单都有一个唯一ID,PID(父级ID),现在需要扩展的功能,就是添加一个button按钮控制,其中主要的细节交互:

  1. 取消选中子级menu/button,父级不关联取消;
  2. 选中/取消父级catalog/menu,子级全部选中/取消;
  3. 选中/取消部分子级menu/button,父级关联半选中状态(indeterminate=true);

其中我用的是el-tree 组件,我用button:xxx业务按钮;这样的方式来命名,后端也给了区分类型的字段type:catalog(目录),menu(菜单),button(按钮)。

在这里插入图片描述

el-tree 中 check-strictly 属性

el-tree 中 check-strictly 属性,为了实现取消选中子级menu/button,父级不关联取消,这里check-strictly设置为true;设置后点击父级也不关联子级选中了,用户用起来不方便,这里就需要我们自己处理
在这里插入图片描述

二、处理父级的半选中以及选中交互

el-tree

 <el-treeref="treeRef":check-strictly="true":data="treeData"show-checkboxdefault-expand-allnode-key="id"highlight-current:default-checked-keys="variable.roleForm.featureIds":props="defaultProps"@check="hanleCheck"@check-change="checkChange"/>
const defaultProps = {children: 'children',label: function (treeData: any, treeNode: any) {return treeData?.name}
}

check,check-change 事件

这里主要用的事件 check,check-change
在这里插入图片描述

const hanleCheck = (data:any, node:any) => {console.log(data, node);// 获取当前节点是否被选中const isChecked = treeRef.value!.getNode(data).checked// 如果当前节点被选中,则遍历下级子节点并选中,如果当前节点取消选中,则遍历下级节点并取消if (isChecked) {// 判断该节点是否有下级节点,如果有那么遍历设置下级节点为选中data.children && data.children.length > 0 && setChildreChecked(data.children, true)} else {// 如果节点取消选中,则取消该节点下的子节点选中data.children && data.children.length > 0 && setChildreChecked(data.children, false)}function setChildreChecked(node:any, isChecked:boolean) {node.forEach((item:any) => {item.children && item.children.length > 0 && setChildreChecked(item.children, isChecked)// // 修改勾选状态treeRef.value!.setChecked(item.id, isChecked,false)})}
}const checkChange = (data, checked, indeterminate) => {// console.log(data, checked, indeterminate);// 选中全部子节点,父节点也默认选中,但是子节点再次取消勾选或者全部子节点取消勾选也不会影响父节点勾选状态let checkNode = treeRef.value!.getNode(data)//获取当前节点// 勾选部分子节点,父节点变为半选状态if (checkNode.parent && checkNode.parent.childNodes.some(ele => ele.checked)) {checkNode.parent.indeterminate = true}// 勾选全部子节点,父节点变为全选状态if (checkNode.parent && checkNode.parent.childNodes.every(ele => ele.checked)) {checkNode.parent.checked = truecheckNode.parent.indeterminate = false}// 如果取消所有第二节点的勾选状态,则第一层父节点也取消勾选if (checkNode.level == 2 && checkNode.parent.childNodes.every(ele => !ele.checked)) {checkNode.parent.checked = falsecheckNode.parent.indeterminate = false}
}

其中,上面用的

      treeRef.value!.setChecked(item.id, isChecked,false)

看文档说第三个属性是是否要递归,我觉得是设置了true后,应该帮我递归选中/取消关联的节点,但没有生效,所以还是自己递归下;(有大佬能指出是我的用法有问题吗?劳烦指出)
在这里插入图片描述

编辑进来,父级的半选状态处理

上述方法实现后,我们就可以实现上述交互了,但这里要注意的一点,就是点击编辑进入的,父级的半选状态没有选中,也就是说 checkNode.parent.indeterminate 这个没有被设置为true;下面打个补丁。

const editRole = async (row: any) => {const { permissionIds} = await detailApi({ id: row.id })await nextTick()setCheckedKeys(permissionIds)  // 返回用户的权限id后,根据id选中树节点permissionIds.forEach((id:any) => {const nodeData = treeRef.value!.getNode(id)  // 根据权限id,获取每个选中的树节点console.log('nodeData',nodeData)console.log('nodeData.parent?.id',nodeData.parent?.id)// 反显,上面setCheckedKeys后,如果父级没有选中,则把半选状态设置trueif(nodeData?.parent?.id != 0 &&  !nodeData?.parent?.checked){nodeData.parent.indeterminate = true}});
}

总结

后台管理系统常见的权限控制需求,这里讲button实现交互细节处理,

  1. 取消选中子级menu/button,父级不关联取消;
  2. 选中/取消父级catalog/menu,子级全部选中/取消;
  3. 选中/取消部分子级menu/button,父级关联半选中状态(indeterminate=true);
    下篇再补上button 的根据权限控制显示,用vue3 的指令实现,谢谢关注
http://www.lryc.cn/news/166636.html

相关文章:

  • js中事件委托和事件绑定之间的区别
  • Android 11.0 系统system模块开启禁用adb push和adb pull传输文件功能
  • 实战经验分享:如何通过HTTP代理解决频繁封IP问题
  • 通讯网关软件001——利用CommGate X2Access-U实现OPC UA数据转储Access
  • Mybatis sql参数自动填充
  • 亚马逊云科技面向游戏运营活动的AI生图解决方案
  • 腾讯mini项目-【指标监控服务重构】2023-07-30
  • Windows 下 MySQL 8.1 图形化界面安装、配置详解
  • WebRTC 源码 编译 iOS端
  • Python编程指南:利用HTTP和HTTPS适配器实现智能路由
  • MySQL 权限分配
  • 基于PHP的医药博客管理系统
  • spark SQLQueryTestSuite sql 自动化测试用例
  • Taro小程序隐私协议开发指南填坑
  • iOS App上传到苹果应用市场构建版本的图文教程
  • paddle框架的使用
  • Spring Boot + Vue的网上商城之基于element ui后台管理系统搭建
  • Linux基础入门
  • Unity工具——LightTransition(光照过渡)
  • 【深度学习】 Python 和 NumPy 系列教程(十四):Matplotlib详解:1、2d绘图(下):箱线图、热力图、面积图、等高线图、极坐标图
  • IMU+摄像头实现无标记运动捕捉
  • 前后端分离,JSON数据如何交互
  • docker中已创建容器的修改方法
  • uniapp中video播放视频上按钮没显示的问题
  • docker学习:dockerfile和docker-compose
  • Pycharm 配置python项目本地运行环境
  • DevEco Studio中如何设置HarmonyOS/OpenHarmony应用开发
  • Matlab图像处理-三原色
  • QLExpress代码解读,运行原理解析
  • M1 Mac创建虚拟环境遇到的问题