el-tree父子不互相关联时,手动实现全选、反选、子级全选、清空功能

el-tree父子不互相关联时,手动实现全选、反选、子级全选、清空功能

1、功能实现图示

2、实现思路

当属性check-strictly为true时,父子节点不互相关联,如果需要全部选中或选择某一节点下的全部节点就必须手动选择每个节点,十分麻烦。可以通过ref操做el-tree的getCheckedKeys、getCheckedNodes、setCheckedKeys方法手动快速节点选择。

3、代码实现

vue 复制代码
<template>
  <div class="list_tree">
    <div class="flex mb10">
      <el-button
        v-for="item in treeButtonProps"
        size="mini"
        type="primary"
        class="mr5"
        :key="item.treeKey"
        :disabled="item.isDisb ? isdisChildAll : false"
        @click="onChecked(item.treeKey)"
      >
        {{ item.text }}
      </el-button>
    </div>
    <el-tree
      ref="treeRef"
      :data="treeData"
      show-checkbox
      node-key="deptId"
      check-strictly
      default-expand-all
      @check-change="checkChange"
    />
  </div>
</template>

<script>
export default {
  data() {
    return {
      // tree数据结构....
      treeData: [
        {
          deptId: '130200',
          label: '河北省/唐山市',
          pid: null,
          regionCode: '130200',
          type: '1',
          topId: null,
          children: [
            {
              deptId: '13020001',
              label: '唐山教育局',
              pid: '130200',
              regionCode: '130200',
              type: '2',
              topId: '130200',
              children: [
                {
                  deptId: '130200001',
                  label: '唐山初级中学校',
                  pid: '13020001',
                  regionCode: '130200',
                  type: '2',
                  children: null,
                  topId: '130200'
                },
                {
                  deptId: '130200002',
                  label: '唐山市初级二中',
                  pid: '13020001',
                  regionCode: '130200',
                  type: '2',
                  children: null,
                  topId: '130200'
                }
              ]
            }
          ]
        }
        /// more-data.......
      ],
      isdisChildAll: false,
      treeKeysList: [],
      treeButtonProps: [
        { text: '全选', isDisb: false, treeKey: 'all' },
        { text: '反选', isDisb: false, treeKey: 'reverse' },
        { text: '子级全选', isDisb: true, treeKey: 'childAll' },
        { text: '清空', isDisb: false, treeKey: 'clear' }
      ]
    };
  },
  methods: {
    // 获取树所有key集合
    getTreeKeys() {
      this.treeKeysList = [];
      const treeData = deepClone(this.treeData);
      while (treeData.length > 0) {
        const item = treeData.pop();
        this.treeKeysList.push(item.deptId);
        if (item.children && item.children.length > 0) {
          treeData.push(...item.children);
        }
      }
    },
    // 设置子级全选是否禁用
    checkChange(data, checked) {
      // 没有选中含有子级节点时禁用
      if (checked) {
        this.isdisChildAll = !(data.children && data.children.length > 0);
      } else {
        this.isdisChildAll = true;
      }
    },
    // 全选、反选、子级全选、清空
    onChecked(type) {
      // 最终选中的keys
      let setKeysList = [];
      const treeNode = this.$refs.treeRef;
      // 已选中keys
      const checkedKeys = treeNode.getCheckedKeys();
      if (type == 'clear') {
        setKeysList = [];
      }
      if (type == 'all') {
        setKeysList = this.treeKeysList;
      }
      if (type == 'reverse') {
        // 未选中keys集合
        setKeysList = this.treeKeysList.filter(item => checkedKeys.indexOf(item) == -1);
      }
      if (type == 'childAll') {
        setKeysList = checkedKeys;
        // 目前被选中的节点所组成的数组
        const checkNodes = treeNode.getCheckedNodes();
        // 筛选出有子节点的node
        const hasChildNodes = checkNodes.filter(item => item.children && item.children.length > 0);
        // 循环遍历出子节点集合
        while (hasChildNodes.length > 0) {
          const item = hasChildNodes.pop();
          setKeysList.push(item.deptId);
          if (item.children && item.children.length > 0) {
            hasChildNodes.push(...item.children);
          }
        }
      }
      // 设置节点选中状态
      treeNode.setCheckedKeys(setKeysList);
    }
  }
};
</script>

本文由博客一文多发平台 OpenWrite 发布!

相关推荐
汤米粥4 天前
2026年主流前端技术框架
vue·react·elementplus·tailwind css·angular‌·svelte‌·bootstrap‌
codigger4 天前
Vue nextTick 到底在等什么?一篇讲透原理与那些年踩过的坑
程序员·vue·编程·异步更新·#人工智能
咚咚咚小柒5 天前
【前端】LangChain.js学习
前端·javascript·人工智能·typescript·langchain·vue·ai编程
悟道书生7 天前
若依 RBAC 权限控制学习笔记
java·网络·笔记·sql·学习·vue
mewowaBc7 天前
使用Pinia持久化存储实现用户认证系统
vue·pinia·用户认证系统
gc_22998 天前
使用VS Code终端创建Vue项目报错:“npm : 无法加载文件 ...\npm.ps1,因为在此系统上禁止运行脚本”
vue·vs code
小阿鑫8 天前
尤雨溪 : Vue 4 已经在规划中了!
vue·vite·vite+·程序员海军·vue4
离歌漠9 天前
《我用 Tauri 做了一个本地开发工具箱》
rust·typescript·vue
enjoy编程9 天前
playwright学习-I
typescript·vue·nodejs·1024程序员节·playwright
落花看风雪11 天前
从零开始搭建后台系统(vue3+TypeScript+Vite)01
typescript·vue·js