el-tree 树结构实现父子不关联(check-strictly) 且能全选、反选、半选

需求: Tree 树形控件需要实现父子不关联勾选,但同时也要实现全选、反选、半选功能 由于按照官网设置check-strictly后,最顶级“全部”也属于父级导致选中全部但未实现全选等功能,又想父子不关联又想全选,那就需要手动写逻辑啦
效果:
el-tree 树结构实现父子不关联(check-strictly) 且能全选、反选、半选_第1张图片
el-tree 树结构实现父子不关联(check-strictly) 且能全选、反选、半选_第2张图片

el-tree 树结构实现父子不关联(check-strictly) 且能全选、反选、半选_第3张图片

解决:单独把全部抽离出来,拉平树结构数据,根据选中长度同拉平后的数据长度进行对比实现全选、反选、半选
上代码:

<template>
  <div>
    <el-checkbox v-model="checkecd" :indeterminate="indeterminate" @change="checkedAll">
      全部
    </el-checkbox>
    <el-tree ref="tree" :data="treeData" show-checkbox node-key="id" check-strictly @check-change="checkChange">
    </el-tree>
  </div>
</template>

<script>
export default {
  data() {
    return {
      treeData: [
        {
          id: 1,
          label: '一级 1',
          children: [
            {
              id: 4,
              label: '二级 1-1',
              children: [
                {
                  id: 9,
                  label: '三级 1-1-1'
                },
                {
                  id: 10,
                  label: '三级 1-1-2'
                }
              ]
            }
          ]
        },
        {
          id: 2,
          label: '一级 2',
          children: [
            {
              id: 5,
              label: '二级 2-1'
            },
            {
              id: 6,
              label: '二级 2-2'
            }
          ]
        },
        {
          id: 3,
          label: '一级 3',
          children: [
            {
              id: 7,
              label: '二级 3-1'
            },
            {
              id: 8,
              label: '二级 3-2'
            }
          ]
        }
      ], // 树形数据
      levelData: [], // 拉平后的treeData
      checkecd: false,// 全选状态
      indeterminate: false // 半选状态
    }
  },
  created() {
    this.getLevelData()
  },
  methods: {
    // 获取拉平后的数据
    getLevelData() {
      let cloneData = JSON.parse(JSON.stringify(this.treeData))
      this.levelData = this.recursion(cloneData)
    },
    // 全选、反选
    checkedAll() {
      if (this.checkecd) {
        this.$refs.tree.setCheckedNodes(this.levelData)
      } else {
        this.$refs.tree.setCheckedNodes([])
      }
    },
    // 树结构勾选
    checkChange(item, isChecked) {
      // 获取勾选的数据
      let checkNode = this.$refs.tree.getCheckedKeys()
      // 如果勾选数量===拉平后的treeData的数量 那么相当于全选 反之则是反选
      // 如果小于数组数量则是半选
      if (checkNode.length === this.levelData.length) {
        this.checkecd = true
        this.indeterminate = false
      } else if (checkNode.length === 0) {
        this.checkecd = false
        this.indeterminate = false
      } else if (checkNode.length < this.levelData.length) {
        this.indeterminate = true
      }
    },
    // 递归调用
    recursion(arr) {
      return [].concat(...arr.map(item => {
        if (item.children) {
          let arr = [].concat(item, ...this.recursion(item.children))
          delete item.children
          return arr
        }
        return [].concat(item)
      }
      ))
    }
  }
}
</script>

你可能感兴趣的:(笔记,javascript,vue.js,前端,elementui)