使用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>
以上是我处理的方式, 如果有更好的方式, 请兄弟们指教