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

使用el-tree封装一个权限管理的小功能

使用el-tree封装一个权限管理的小功能

在这里插入图片描述
在这里插入图片描述
使用el-tree封装权限管理, 选中人员并且在右侧回显, 此组件用到了递归, 我只是将需要显示的数据进行了动态传递, 其他数据小伙伴可以自己封装

父组件

<template><div><authorityManage ref="authorityManage" :deptData="data"></authorityManage><el-button class="saveBtn" @click="saveBtnClick()">保存</el-button><el-button class="saveBtn" @click="editBtnClick()">回显数据(编辑 [曹丕] )</el-button></div>
</template><script>
import authorityManage from './common/authorityManage.vue'
export default {name: "index",components: {authorityManage},data(){return {data: [{id: 1,name: '部门A',parentId: 0,},{id: 2,parentId: 1,name: '曹操',},{id: 230,parentId: 2,name: '曹丕'},{id: 231,parentId: 2,name: '曹植'},{id: 3,parentId: 1,name: '司马懿'},{id: 20,name: '部门B',parentId: 0,},{id: 21,name: '刘备',parentId: 20,},]}},methods: {saveBtnClick(){let data = this.$refs.authorityManage.submitData();console.log(data,'data')},editBtnClick(){let list = [{authority: "1",copyContent: "0",download: "1",id: 230,name: "曹丕",parentId:2,printing: "0",}]this.$refs.authorityManage.editData(list)},}
}
</script><style scoped>
.saveBtn{margin-top: 10px;
}
</style>

子组件

<template><div><div class="manage"><div class="personnel"><div class="header">未选</div><div class="content"><el-tree :props="defaultProps" ref="tree" :data="deptTreeData" node-key="id" show-checkbox @check="handleCheckChange"></el-tree></div></div><div class="authority"><div class="header"><div>已选</div><div><el-dropdown><span class="el-dropdown-link">{{ form.authority ? authorityMatter(form.authority) : '权限' }} <i class="el-icon-arrow-down el-icon--right"></i></span><el-dropdown-menu slot="dropdown"><div class="dropdownBox" style=""><div class="dropdownBox_left"><div class="title">文档权限</div><div class="permissionList"><el-radio v-model="form.authority" :label="item.value" v-for="(item,key) in authorityOptions" :key="key">{{ item.label }}</el-radio></div></div><div class="dropdownBox_right"><div class="title">文档保护</div><div class="permissionList"><div class="switch"><div class="title">下载</div><div><el-switch active-value="1" inactive-value="0" v-model="form.download"></el-switch></div></div><div class="switch"><div class="title">打印</div><div><el-switch active-value="1" inactive-value="0" v-model="form.printing"></el-switch></div></div><div class="switch"><div class="title">复制内容</div><div><el-switch active-value="1" inactive-value="0" v-model="form.copyContent"></el-switch></div></div></div></div></div></el-dropdown-menu></el-dropdown></div></div><div class="content"><el-tree :props="defaultProps" :data="selectDeptTreeData"></el-tree></div></div></div></div>
</template><script>
export default {name: "authority",data(){return {form: {authority: '', // 权限download: '0', // 下载printing:'0', // 打印copyContent: '0', // 复制内容},// 权限optionsauthorityOptions: [{label: '仅查看',value: '1'},{label: '可编辑',value: '2'},{label: '可批注',value: '3'},{label: '可审核',value: '4'},{label: '禁止访问',value: '5'},],// 部门数据deptTreeData: [],defaultProps: {children: 'children',label: 'name',},// 已选择部门人员selectDeptData: [],// 已选择的部门人员树状数据selectDeptTreeData: [],}},props: {// 父组件传递的数据deptData: {default: null,type: Array,}},mounted() {this.initData()},methods: {/**接受父组件传递的数据, 并格式化为树状数据图形左侧使用 */initData(){this.deptTreeData = this.treeLikeData(this.deptData, 0,);},/**权限label格式化 */authorityMatter(){let filterList = this.authorityOptions.filter(item=>item.value == this.form.authority);if (filterList.length){return filterList[0].label;}},/**树状数据change事件 */handleCheckChange(data){// 1(if),判断是否有children, 如果有children, 需要将children里的数据取出,// 2(else),如果没有children, 需要通过pid查询出上一级, 直到pid为0if (data.children.length){let resoltData = this.recursionGetChildrenData(data,[]);this.mergeData(resoltData,);if (data.parentId !== 0){let resoltData = this.adoptPidGetPreviousLevelData(data);this.mergeData(resoltData);}} else {let resoltData = this.adoptPidGetPreviousLevelData(data);this.mergeData(resoltData);}this.selectDeptTreeData = this.treeLikeData(this.selectDeptData, 0,);},/**通过递归, 将children里的数据全部取出 */recursionGetChildrenData(data, recoverList){let dataObj = {id: data.id,name: data.name,parentId: data.parentId,}let list = recoverList;list.push(dataObj)let childData = function(data){data.forEach(item=>{let obj = {id: item.id,name: item.name,parentId: item.parentId,}list.push(obj);if (item.children.length){childData(item.children);}})return list;}return childData(data.children, list)},/**通过pid获取上一级数据, 直到pid为0 */adoptPidGetPreviousLevelData(data){let deptData = this.deptData;let list = [];let dataObj = {id: data.id,name: data.name,parentId: data.parentId}list.push(dataObj);let getPreviouseData = function(data){let index = deptData.map(item=>item.id).indexOf(data.parentId);if (index !== -1){let obj = {id: deptData[index].id,name: deptData[index].name,parentId: deptData[index].parentId,}list.push(obj);if (obj.pid !== 0){getPreviouseData(obj);}}return list;}return getPreviouseData(data);},/**将过滤出来的数据合并到selectDeptData里, 如果过滤出来的数据存在在selectDeptData,需要删除,如果不存在,则添加 */mergeData(data){if (data.length){data.forEach(item=>{let index = this.selectDeptData.map(mapItem=>mapItem.id).indexOf(item.id);let pidIndex = this.selectDeptData.map(mapItem=>mapItem.parentId).indexOf(item.id);// 查询当前数据是否存在selectDeptData里, 如果存在,需要删除if (index !== -1 && pidIndex == -1){let treeNode = this.$refs.tree.getNode(item.id);if (treeNode && !treeNode.checked){this.selectDeptData.splice(index, 1);}} else {// 查看当前数据是否在selectDeptData里, 如果不存在就添加, 防止重复添加let index = this.selectDeptData.map(mapItem=>mapItem.id).indexOf(item.id);if (index == -1){this.selectDeptData.push(item);}}})}},/**提交数据 */submitData(){let data = this.getBottomData();return data;},/**查询已选择数据的最底层, 为其赋权限 */getBottomData(){let list = [];let _this = this;let child = function(data){data.forEach(item=>{if (item.children.length){child(item.children)} else {let obj = {id: item.id,name: item.name,parentId: item.parentId,authority: _this.form.authority, // 权限download: _this.form.download, // 下载printing: _this.form.printing, // 打印copyContent: _this.form.copyContent, // 复制内容}list.push(obj);}})return list;}return child(this.selectDeptTreeData)},/**编辑回显数据 */editData(data){let idList = [];if (data.length){data.forEach(item=>{idList.push(item.id);this.form.authority = item.authority;this.form.download = item.download;this.form.printing = item.printing;this.form.copyContent = item.copyContent;let resoltData = this.adoptPidGetPreviousLevelData(item);this.mergeData(resoltData);})this.selectDeptTreeData = this.treeLikeData(this.selectDeptData, 0,);}this.setCheckedKeys(idList)},/**通过key设置选中数据 */setCheckedKeys(idList){this.$refs.tree.setCheckedKeys(idList);},/**格式化数据, 将数据格式化为树状数据 */treeLikeData (list, parentID, parentIdName) {let parentName = parentIdName ? parentIdName : 'parentId';//定义一个用于递归查找子元素的函数var child = function (pareID) {//先定义一个数组,用于存储所查到的子元素var childs = [];//循环数组for (let i = 0; i < list.length; i++) {//如果数组其中一项的parentId等于传入的,说明这一项是传入的子元素,把他push进数组,然后重复递归自己找该项的子元素if (list[i][parentName] == pareID) {list[i].children = child(list[i].id);childs.push(list[i])}}//最后将查到的所有子元素返回return childs;};return child(parentID)},}
}
</script><style scoped lang="scss">
.el-dropdown-menu{width: 300px;.dropdownBox{display: flex;padding: 10px;box-sizing: border-box;font-size: 14px;.dropdownBox_left{width: 100px;border-right: 1px solid #ccc;.permissionList{.el-radio{margin-top: 10px;}}}.dropdownBox_right{flex: 1;padding: 0 10px;box-sizing: border-box;.permissionList{.switch{display: flex;align-items: center;margin-top: 10px;.title{width: 80px;}}}}}
}.manage{width: 600px;height: 500px;border: 2px solid #ccc;display: flex;justify-content: space-between;.personnel{width: 50%;height: 100%;border-right: 1px solid #ccc;.header{height: 40px;display: flex;align-items: center;padding: 0 10px;box-sizing: border-box;background: #ddd;}.content{height: calc(100% - 40px);padding: 0 10px;box-sizing: border-box;}}.authority{width: 50%;height: 100%;.header{height: 40px;display: flex;align-items: center;justify-content: space-between;padding: 0 10px;box-sizing: border-box;background: #ddd;}.content{height: calc(100% - 40px);}}
}
</style>

以上是我处理的方式, 如果有更好的方式, 请兄弟们指教

相关文章:

  • C++笔试强训day41
  • vue3+ts webVTT与JSON之前格式互转
  • 前端预览pdf文件(后端返回pdf文件流)
  • Spring Cloud、Spring Cloud LoadBalancer、Nacos 和 OpenFeign整合
  • [ 网络通信基础 ]——网络的传输介质(双绞线,光纤,标准,线序)
  • hnust 湖南科技大学 2022 软件测试报告+代码
  • 宏集Panorama SCADA:个性化定制,满足多元角色需求
  • Apple开发者应用商店(AppStore)描述文件及ADHOC描述文件生成
  • 深拷贝、浅拷贝、引用拷贝
  • 台湾合泰原装BS66F360 封装LQFP-44 电容触摸按键 AD+LED增强型触控
  • 【Mac】Downie 4 for Mac(视频download工具)兼容14系统软件介绍及安装教程
  • 算法课程笔记——蓝桥第17次直播云课
  • window.clearInterval(timer) 清除定时器
  • React Native采集数据离线存储、网络状态监控、加密上传、鉴权
  • 4.通用编程概念
  • 「前端早读君006」移动开发必备:那些玩转H5的小技巧
  • 0基础学习移动端适配
  • 10个最佳ES6特性 ES7与ES8的特性
  • canvas 高仿 Apple Watch 表盘
  • Centos6.8 使用rpm安装mysql5.7
  • express + mock 让前后台并行开发
  • niucms就是以城市为分割单位,在上面 小区/乡村/同城论坛+58+团购
  • nodejs:开发并发布一个nodejs包
  • SSH 免密登录
  • Synchronized 关键字使用、底层原理、JDK1.6 之后的底层优化以及 和ReenTrantLock 的对比...
  • vue:响应原理
  • Zsh 开发指南(第十四篇 文件读写)
  • 大型网站性能监测、分析与优化常见问题QA
  • 前端设计模式
  • 如何编写一个可升级的智能合约
  • 用mpvue开发微信小程序
  • ​​​​​​​Installing ROS on the Raspberry Pi
  • ​数据结构之初始二叉树(3)
  • $Django python中使用redis, django中使用(封装了),redis开启事务(管道)
  • (C语言)fgets与fputs函数详解
  • (Java岗)秋招打卡!一本学历拿下美团、阿里、快手、米哈游offer
  • (k8s)kubernetes集群基于Containerd部署
  • (PWM呼吸灯)合泰开发板HT66F2390-----点灯大师
  • (Redis使用系列) SpringBoot 中对应2.0.x版本的Redis配置 一
  • (二)学习JVM —— 垃圾回收机制
  • (分布式缓存)Redis分片集群
  • (附源码)spring boot基于Java的电影院售票与管理系统毕业设计 011449
  • (附源码)springboot宠物管理系统 毕业设计 121654
  • (收藏)Git和Repo扫盲——如何取得Android源代码
  • (顺序)容器的好伴侣 --- 容器适配器
  • (一)十分简易快速 自己训练样本 opencv级联haar分类器 车牌识别
  • (译)2019年前端性能优化清单 — 下篇
  • (转)用.Net的File控件上传文件的解决方案
  • **登录+JWT+异常处理+拦截器+ThreadLocal-开发思想与代码实现**
  • .NET 材料检测系统崩溃分析
  • .net对接阿里云CSB服务
  • .net连接MySQL的方法
  • /dev/VolGroup00/LogVol00:unexpected inconsistency;run fsck manually
  • @Builder用法
  • @FeignClient 调用另一个服务的test环境,实际上却调用了另一个环境testone的接口,这其中牵扯到k8s容器外容器内的问题,注册到eureka上的是容器外的旧版本...