基于elementui的折叠面板,实现二级的树形结构

本文介绍如何将ElementUI的el-tree组件改造成折叠面板,以在弹窗中实现二级目录的横向展示。通过使用el-collapse和el-collapse-item组件,结合el-checkbox-group和el-checkbox,实现了在页面上展示并交互的功能。同时,文章详细讲解了如何处理父子级复选框的联动逻辑,包括全选、半选和单选的切换效果。
摘要由CSDN通过智能技术生成

因为el-tree在弹窗中显示较为孤立,显得页空旷,改装elementui的折叠面板,实现二级目录横向展示、

效果图

在这里插入图片描述

<template>
  <div class="container">
    <el-collapse v-model="activeNames">
      <el-collapse-item v-for="(item, index) in ResourceOption" :key="index" :name="item.name">
        <template slot="title">
          <el-checkbox-group v-model="checkAll" @change="handleCheckAllChange(item)">
            <el-checkbox :indeterminate="item.isIndeterminate" :label="item.id">{{ item.name }}</el-checkbox>
          </el-checkbox-group>
        </template>
        <div class="children_item" v-show="item.children">
          <el-checkbox-group v-model="checkedChildren">
            <el-checkbox
              v-for="(temp, i) in item.children"
              :key="i"
              :label="temp.id"
              @change="handleCheckedChildrenChange(temp)"
              >{{ temp.name }}
              <el-button
                v-show="temp.children.length > 0"
                icon="el-icon-search"
                @click="tabChildrenDialog"
                circle
              ></el-button>
            </el-checkbox>
          </el-checkbox-group>
        </div>
      </el-collapse-item>
    </el-collapse>
  </div>
</template>
<script>
export default {
  props: {
    ResourceOption: {
      type: Array,
      default: () => [],
    },
  },

  data() {
    return {
      activeNames: [],
      isIndeterminate: false,
      checkAll: [],
      checkedChildren: [],
      checkedChildrenItem: [],
      fatherIdList: [],
      fatherItemList: [],
    };
  },
  methods: {
    tabChildrenDialog() {},

    // 父级折叠栏目 点击复选框
    handleCheckAllChange(val) {
      this.noChooseFather(val);
    },
    // 如果此标签未选择,父级选择自动携带全部子级
    noChooseFather(val) {
      if (this.fatherIdList.includes(val.id)) {
        if (this.isIndeterminateTab(val.id)) {
          this.setResourceisIndeterminate(val.id, false);
        }
        console.log(121);
        // 如果包含id,说明此选项已勾选,需要取消此选项,并取消其全部子级
        // 找到id在数组中的下标,并将下标删除
        const index = this.fatherIdList.indexOf(val.id);
        // 将该下标的id删除,
        if (index !== -1) {
          this.fatherIdList.splice(index, 1);
        }

        // 将该id对应的item删除
        this.delFatherListItem(val.id);
        // 将对应的子级删除
        this.delThisChildrenList(val.id);
      } else {
        // this.setResourceisIndeterminate(val.id, false);
        // console.log(this.isIndeterminateTab(val.id));
        if (this.isIndeterminateTab(val.id)) {
          this.setResourceisIndeterminate(val.id, false);
        }

        // 不包含id,说明此选项未勾选,需要将id,item进行存储,并勾选全部子级
        this.fatherIdList.push(val.id);
        console.log(this.fatherIdList);
        this.fatherItemList.push(val);
        // 全选子级
        this.chooseAllchildren(val);
      }
    },
    // 判断该级是否半选
    isIndeterminateTab(id) {
      let flag = false;
      this.ResourceOption.forEach(item => {
        if (item.id === id) {
          flag = item.isIndeterminate;
        }
      });
      return flag;
    },
    // 全选子级
    chooseAllchildren(val) {
      this.ResourceOption.forEach(item => {
        if (item.id === val.id) {
          item.children.forEach(ele => {
            this.checkedChildren.push(ele.id);
            this.checkedChildrenItem.push(ele);
            this.fatherIdList.push(ele.id);
            this.fatherItemList.push(ele);
          });
        }
      });
      console.log(this.checkedChildren);
      this.checkedChildren = [...new Set(this.checkedChildren)];
      this.fatherIdList = [...new Set(this.fatherIdList)];
      this.fatherItemList = [...new Set(this.fatherItemList)];
      console.log(this.fatherIdList);
    },
    // 删除fatherItemList对应id的item
    delFatherListItem(id) {
      this.fatherItemList.forEach((item, index) => {
        if (item.id === id) {
          this.fatherItemList.splice(index, 1);
        }
      });
    },

    // 根据id的位置,删除数组元素
    delArrayByIndex(Arr, id) {
      const index = Arr.indexOf(id);
      if (index !== -1) {
        Arr.splice(index, 1);
      }
    },
    // 删除对应的子级
    delThisChildrenList(id) {
      //   // 需要被删除的id数组
      //   const idArr = [];
      // 需要被删除的item数组
      let itemArr = [];
      this.ResourceOption.forEach(item => {
        if (item.id === id) {
          itemArr = item.children;
        }
      });
      // 在该父级的子级中找到所有的id,并在fatherIdList中找到下标后删除
      itemArr.forEach(ele => {
        // 找到对应的id位置
        // const index = this.fatherIdList.indexOf(ele.id);
        // 删除对应的子级id
        // this.fatherIdList.splice(index, 1);
        this.delArrayByIndex(this.fatherIdList, ele.id);
        this.delArrayByIndex(this.checkedChildren, ele.id);

        // // 删除对应的checkedChildren中的id
        // const i = this.checkedChildren.indexOf.indexOf(ele.id);
        // // 删除对应的子级id
        // this.checkedChildren.splice(i, 1);
      });
      console.log(this.checkedChildren);
      // 在fatherItemList中找到对应的item下标后删除

      itemArr.forEach(temp => {
        this.fatherItemList.forEach((item, index) => {
          if (temp.id === item.id) {
            this.fatherItemList.splice(index, 1);
          }
        });
        this.checkedChildrenItem.forEach((item, index) => {
          if (temp.id === item.id) {
            this.checkedChildrenItem.splice(index, 1);
          }
        });
      });
    },

    // 删除对应id的item
    delItemById(Arr, id) {
      Arr.forEach((item, index) => {
        if (item.id === id) {
          Arr.splice(index, 1);
        }
      });
    },
    // 选择子级时候,如果子级未选中,选中子级,父级需要半选
    handleCheckedChildrenChange(temp) {
      console.log(temp);
      // 判断子级是否全部选中
      const childrenIdArr = this.getFatherChildrenByPId(temp.pId);
      // 先判断公共list中是否包含该id,然后再决定是否在公共list中存放 对应的id 和item
      if (this.fatherIdList.includes(temp.id)) {
        // 如果公共list中包含该id,说明已经被选中
        // 需要在checkedChildren checkedChildrenItem中删除对应的id,item
        // 并且在fatherIdList,fatherItemList中一并删除

        //  this.delArrayByIndex(this.checkedChildren, temp.id);
        this.delItemById(this.checkedChildrenItem, temp.id);
        this.delArrayByIndex(this.fatherIdList, temp.id);
        this.delItemById(this.fatherItemList, temp.id);
        console.log(this.fatherIdList);

        if (!this.isIncludes(this.fatherIdList, childrenIdArr)) {
          this.setResourceisIndeterminate(temp.pId, true);
          // this.isIndeterminate = true;
        } else {
          this.setResourceisIndeterminate(temp.pId, false);
          this.delArrayByIndex(this.checkAll, temp.pId);
          this.delArrayByIndex(this.checkedChildren, temp.id);
          this.delArrayByIndex(this.fatherIdList, temp.pId);
          this.delItemById(this.fatherItemList, temp.pId);
          console.log(this.fatherIdList);
        }
      } else {
        console.log(this.checkedChildren);

        this.fatherIdList.push(temp.id);
        this.fatherItemList.push(temp);
        console.log(childrenIdArr);
        console.log(this.fatherIdList);
        console.log(this.fatherIdList.includes(childrenIdArr));
        if (this.isIncludes(this.fatherIdList, childrenIdArr)) {
          // 完全包含
          this.setResourceisIndeterminate(temp.pId, false);
          this.fatherIdList.push(temp.pId);
          this.checkAll.push(temp.pId);
          console.log(this.fatherIdList);
          this.AddItemByid(temp.pId);
        } else {
          // 半选
          this.setResourceisIndeterminate(temp.pId, true);
        }
      }
    },
    // ResourceOption赋值属性是否半选
    setResourceisIndeterminate(id, flag) {
      this.ResourceOption.forEach(item => {
        if (item.id === id && flag) {
          item.isIndeterminate = true;
        }
        if (item.id === id && !flag) {
          item.isIndeterminate = false;
        }
      });
    },
    // 根据id获取ResourceOption的item
    AddItemByid(id) {
      this.ResourceOption.forEach(item => {
        if (id === item.id) {
          this.fatherItemList.push(item);
        }
      });
    },
    isIncludes(arr1, arr2) {
      let flag = arr2.every(val => arr1.includes(val));
      console.log('22222', flag);
      let count = 0;
      arr2.forEach(item => {
        if (arr1.includes(item)) {
          count += 1;
        }
      });
      if (count === 0) {
        flag = true;
      }
      return flag;
    },
    // 获取当前id的子级的父级的所有子级
    getFatherChildrenByPId(pid) {
      const idArr = [];
      this.ResourceOption.forEach(item => {
        if (item.id === pid) {
          item.children.forEach(temp => {
            idArr.push(temp.id);
          });
        }
      });
      return idArr;
    },
  },
};
</script>
<style scoped>
.container {
  width: 100%;
  height: 400px;
  overflow: auto;
}
.children_item {
  margin-left: 25px;
}
</style>

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值