使用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', // 复制内容
            },
            // 权限options
            authorityOptions: [
                {
                    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为0

            if (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>

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/689632.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Vuepress 2从0-1保姆级进阶教程——标准化流程

Vuepress 2 专栏目录 1. 入门阶段 Vuepress 2从0-1保姆级入门教程——环境配置篇Vuepress 2从0-1保姆级入门教程——安装流程篇Vuepress 2从0-1保姆级入门教程——文档配置篇Vuepress 2从0-1保姆级入门教程——范例与部署 2.进阶阶段 Vuepress 2从0-1保姆级进阶教程——全文搜索…

学习笔记——路由网络基础——路由概述

一、路由概述 1、路由定义与作用 路由(routing)是指导报文转发路径信息&#xff0c;通过路由可以确认转发IP报文的路径。 路由&#xff1a;是指路由器从一个接口上收到数据包&#xff0c;根据数据包的目的地址进行定向并转发到另一个接口的过程。 路由(routing)的定义是指分…

极简主义在UI设计中的应用及解析

极简主义&#xff0c;即“少就是多”。在设计中&#xff0c;极简主义是许多艺术概念之一&#xff0c;它描述了一种内容形式&#xff0c;可以在许多方面使用。现在移动UI界面和网页设计中的极简主义设计越来越多。即时设计认为&#xff0c;极简主义UI界面不仅美观&#xff0c;而…

【一百零八】【算法分析与设计】P1908 逆序对,P1637 三元上升子序列,树状数组区间和应用

P1908 逆序对 逆序对 题目描述 猫猫 TOM 和小老鼠 JERRY 最近又较量上了&#xff0c;但是毕竟都是成年人&#xff0c;他们已经不喜欢再玩那种你追我赶的游戏&#xff0c;现在他们喜欢玩统计。 最近&#xff0c;TOM 老猫查阅到一个人类称之为“逆序对”的东西&#xff0c;这东西…

【漏洞复现】海康威视综合安防管理平台 多处 FastJson反序列化RCE漏洞

0x01 产品简介 海康威视综合安防管理平台是一套“集成化”、“智能化”的平台,通过接入视频监控、一卡通、停车场、报警检测等系统的设备。海康威视集成化综合管理软件平台,可以对接入的视频监控点集中管理,实现统一部署、统一配置、统一管理和统一调度。 0x02 漏洞概述 由于…

在Cisco Packet Tracer上配置NAT

目录 前言一、搭建网络拓扑1.1 配置PC机1.2 配置客户路由器1.3 配置ISP路由器 二、配置NAT2.1 在客户路由器中配置NAT2.2 测试是否配置成功 总结 前言 本篇文章是在了解NAT的原理基础上&#xff0c;通过使用Cisco Packet Tracer 网络模拟器实现模拟对NAT的配置&#xff0c;以加…

源码、反码和补码

对于有符号数而言&#xff0c;原码就是一个数的二进制表示。二进制的最高位是符号位&#xff0c;0 表示正数&#xff0c;1 表示负数。 计算机用数的原码进行显示&#xff0c;数的计算和存储是用补码进行的。 正数的原码&#xff0c;反码和补码都一样&#xff0c;即正数三码合…

Cesium中的坐标系统简单说明(2026-06-08)

一、坐标系统 cesium中坐标系统分为地理坐标、世界坐标&#xff08;X,Y,Z&#xff09;、屏幕坐标三种。 通常使用地理坐标来进行位置表达&#xff0c;笛卡尔空间坐标系常用来做一些空间位置变换如平移旋转缩放&#xff0c;屏幕坐标常用来做用户交互等&#xff0c;三者之间相互…

win7补丁下载

目的 一般来说&#xff0c;安装上windows系统就带着补丁了&#xff0c;但有时&#xff0c;安装的是原始版的操作系统是不带补丁的&#xff0c;一般直接更新就可以了&#xff0c;但有时&#xff0c;电脑不能联网&#xff0c;只能通过安装包进行升级&#xff0c;所以下面介绍如何…

Docker 学习总结(83)—— 配置文件daemon.json介绍及优化建议

一、daemon.json 文件概述 daemon.json是Docker守护进程的配置文件,它允许系统管理员自定义Docker守护程序的行为。此文件通常位于/etc/docker/目录下。通过修改daemon.json,可以调整Docker守护进程的多种设置,包括网络配置、日志记录、存储驱动等。 二、daemon.json 文件结…

【Vue】路由的基本使用

文章目录 一、固定5个固定的步骤二、代码示例三、两个核心步骤四、完整代码 vue-router插件作用 修改地址栏路径时&#xff0c;切换显示匹配的组件 说明 Vue 官方的一个路由插件&#xff0c;是一个第三方包 官网 https://v3.router.vuejs.org/zh/ VueRouter的使用&#xff0…

【安装笔记-20240607-Linux-适合个人用户及初创企业的 SSL 证书服务】

安装笔记-系列文章目录 安装笔记-20240607-Linux-适合个人用户及初创企业的 SSL 证书服务 文章目录 安装笔记-系列文章目录安装笔记-20240607-Linux-适合个人用户及初创企业的 SSL 证书服务 前言一、软件介绍名称&#xff1a;acme.sh主页官方介绍 二、安装步骤测试版本&#x…

React Hooks 封装可粘贴图片的输入框组件(wangeditor)

需求是需要一个文本框 但是可以支持右键或者ctrlv粘贴图片&#xff0c;原生js很麻烦&#xff0c;那不如用插件来实现吧~我这里用的wangeditor插件&#xff0c;初次写初次用&#xff0c;可能不太好&#xff0c;但目前是可以达到实现需求的一个效果啦&#xff01;后面再改进吧~ …

两张图片进行分析

两张图片进行分析&#xff0c;可以拖动左边图片进行放大、缩小查看图片差异 底图 <template><div class"box_container"><section><div class"" v-for"item in imgData.imgDataVal" :key"item.id"><img :s…

JavaSE--【类和对象】

本篇目标 1. 掌握类的定义方式以及对象的实例化 2. 掌握类中的成员变量和成员方法的使用 3. 掌握对象的整个初始化过程 一、面向对象的初步认知 1.1 面向对象的初步认知 Java是一门纯面向对象的语言(Object Oriented Program&#xff0c;简称OOP)&#xff0c;在面向对象的世界里…

Execl数据导入 EasyExcel实现

官网 1. 需求简介 读取下面表格数据 第一行和第二行是计划信息 第三行是计划详情的抬头信息,以下行是计划详情信息 总段包含多个分段,总段使用了单元格合并功能 2. 实现读取功能 2.1 引入easyexcel依赖 <dependency><groupId>com.alibaba</groupId><…

移动端 UI 风格,视觉盛宴

移动端 UI 风格&#xff0c;视觉盛宴

10.dockerfile自动构建镜像

dockerfile自动构建镜像 类似ansible剧本&#xff0c;大小几kb 手动做镜像&#xff1a;大小几百M 首先创建一个dockerfile的路径&#xff0c;便于在路径下存在多个路径每个路径下都是dockerfile命名的脚本 注释&#xff1a;文件必须为&#xff1a;dockerfile或者Dockerfile …

QT中为程序加入超级管理员权限

QT中为程序加入超级管理员权限 Chapter1 QT中为程序加入超级管理员权限1. mingw编译器2. MSVC编译器3. CMAKE Chapter2 如何给QT程序添加管理员权限(UAC)的几种方法1、Qt Creator中方案一&#xff1a;&#xff08;仅适用于使用msvc编译器&#xff09;方案二&#xff1a;&#x…

单链表复习 (C语言版)

目录 一.顺序表与链表的区别 二.链表概念 三.单链表 1.单链表的开始与初始化 2.单链表的打印 3.单链表的尾插 重难点&#xff1a;单链表实现时的指针详解 4.单链表的头插 5.单链表的尾删 6.单链表的头删 小结&#xff1a; 7.单链表的查找 8.在指定位置前插入数据 …