el-table树形复选框(通用组件)

使用方法(将这个注册为组件再使用) 根据element 的 el-table 组件再次封装

 <TableTrees ref="tabTree" :check-list="tableList" :tree-data="treeData" :parent-key="'parentId'" :tree-props="treeProps" :data-column="dataColumn" :row-key="'targetId'" @tabSelectChange="tabSelectChange" />

参数说明 :

:tree-data = treeData  展示的树参数  (树形)(必传)
:check-list = tableList    默认勾选参数
:parent-key = parentId	  父id的名称(key)(必传)
:tree-props = treeProps    树形参数的对象(必传)
:row-key = targetId   根据什么参数判断是否是树(element表格组件自带的)
:data-column = dataColumn    表格字段(必传)
@tabSelectChange    复选框勾选事件 (返回勾选参数的数组)
dataColumn = [
      { prop: 'code', label: '指标编码' },
      { prop: 'name', label: '指标名称', align: 'center' },
      { prop: 'scoreMode', label: '评分方式', align: 'center' }
    ]

表格树组件代表

<template>
  <el-table
    ref="tabled"
    class="sel-table"
    :expand-row-keys="defaultExpandAll"
    :data="dataTree"
    :tree-props="treeProps"
    :row-key="rowKey"
    border
  >
    <el-table-column label="#" width="80" :render-header="renderHeader">
      <template slot-scope="scope">
        <el-checkbox :key="checkboxDatas.length" v-model="scope.row.checked" @change="tabSelectChange(scope.row)" />
      </template>
    </el-table-column>
    <template v-for="(item,index) in dataColumn">
      <el-table-column
        :key="index"
        :label="item.label"
        :prop="item.prop"
        :fixed="item.fixed"
        :type="item.type"
        :width="item.width"
        :class-name="item.class"
        :min-width="item.minWidth"
        :align="item.align"
        :show-overflow-tooltip="item.showTooltip"
      />
    </template>
    <!--    <el-table-column prop="code" label="指标编码" />-->
    <!--    <el-table-column prop="name" label="指标名称" align="center" />-->
    <!--    <el-table-column prop="scoreMode" label="评分方式" align="center" />-->
  </el-table>
</template>

<script>
export default {
  name: 'Index',
  props: {
    treeData: {
      type: Array,
      default: () => []
    },
    treeProps: {
      type: Object,
      default: () => {}
    },
    // 更具什么key判断参数是否存在
    rowKey: {
      type: String,
      default: ''
    },
    dataColumn: {
      type: Array,
      default: () => []
    },
    parentKey: {
      type: String,
      default: ''
    },
    checkList: {
      type: Array,
      default: () => []
    }

  },
  data() {
    return {
      checkboxDatas: [],
      defaultExpandAll: []
    }
  },
  computed: {
    dataTree() {
      let tmp
      if (!Array.isArray(this.treeData)) {
        tmp = [this.treeData]
      } else {
        tmp = this.treeData
      }
      return tmp
    }
  },
  /* created() {
    if (this.dataTree.length > 0) {
      this.dataTree.forEach(x => {
        this.recursiveCheck(x, false)
      })
    }
  },*/
  mounted() {
    this.$nextTick(() => {
      var that = this
      // 初始化 checked为false
      that.dataTree.forEach(x => {
        that.recursiveCheck(x, false)
      })
      // 拿到默认勾选的参数
      if (that.checkList != undefined) {
        that.dataTree.forEach(x => {
          that.checkList.forEach(j => {
            if (x[that.rowKey] == j[that.rowKey]) { // 循环判断,如果相等就调用勾选方法勾选
              x.checked = true
              that.tabSelectChange(x)
            }
          })
        })
      }
      // 最顶上的复选框chanage事件
      const all = document.getElementById('chooseall')
      all.onchange = function(e) {
        if (that.dataTree.length > 0) {
          that.dataTree.forEach(x => {
            x.checked = all.checked
            that.tabSelectChange(x)
            // that.recursiveCheck(x, all.checked)
          })
          // document.getElementById('spand').className += ' el-checkbox__input is-checked' // 设置全选框全选
        }
        /* if (all.checked === true) {
          document.getElementById('spand').className += ' el-checkbox__input is-checked' // 设置全选框全选
        } else {
          document.getElementById('spand').className = 'el-checkbox__input' // 设置全选框的状态
        }*/
      }
    })
  },
  methods: {
    tabSelectChange(row) {
      this.recursiveCheck(row, row.checked)
      var arrListTree = this.treeToList(this.checkboxDatas)
      var jsonTab1 = JSON.parse(JSON.stringify(this.checkboxDatas))
      if (row.checked === true) { // 添加
        if (this.checkboxDatas.length <= 0) {
          this.checkboxDatas.push(row)
        } else {
          var bool = true
          // 如果父id不存在,那么就是顶级,直添加
          if (row[this.parentKey] == undefined) {
            // 循环判断当前表格内的参数是否存在是当前父级的子集  如果存在则调用递归删除后在添加,否则直接添加
            var i = 0
            while (i < jsonTab1.length) {
              if (jsonTab1[i][this.parentKey] == row[this.rowKey] || jsonTab1[i][this.rowKey] == row[this.rowKey]) {
                jsonTab1.splice(i, 1)
              } else {
                i++
              }
            }
            jsonTab1.push(row)
          } else {
            for (let i = 0; i < arrListTree.length; i++) {
              // 如果当前表格内存在父级参数,则递归添加
              if (arrListTree[i][this.rowKey] == row[this.parentKey]) {
                jsonTab1.forEach(x => {
                  if (x[this.rowKey] == row[this.parentKey]) { // 判断是否是当前想的子集  如果是子集 这直接添加
                    x.children.push(row)
                    bool = false
                  } else { // 否则递归添加
                    this.addTree(x, row[this.parentKey], row, bool)
                  }
                })
              } else {
                // 判断选择参数的子是否存在表格内   存在则删除
                if (arrListTree[i][this.parentKey] == row[this.rowKey]) {
                  for (let j = 0; j < jsonTab1.length; j++) {
                    if (jsonTab1[j][this.parentKey] == row[this.rowKey]) {
                      jsonTab1.splice(j, 1)
                    }
                  }
                }
              }
            }
            if (bool === true) {
              jsonTab1.push(row)
            }
          }
          this.checkboxDatas = jsonTab1
        }
      } else { // 删除
        for (let i = 0; i < jsonTab1.length; i++) {
          if (jsonTab1[i][this.rowKey] == row[this.rowKey]) {
            jsonTab1.splice(i, 1)
          } else {
            this.removerTree(jsonTab1[i], row[this.rowKey])
          }
        }
        // this.recursiveCheck(row, row.checked)
        this.checkboxDatas = jsonTab1
      }
      this.$nextTick(() => {
        arrListTree.forEach(x => {
          this.defaultExpandAll.push(x[this.rowKey])
        })
      })
      this.selectClick()
    },
    selectClick() {
      this.$nextTick(() => {
        if (this.checkboxDatas.length == this.dataTree.length) {
          document.getElementById('spand').className = 'el-checkbox__input is-checked' // 设置全选框全选
          document.getElementById('spand').checked = true // 设置全选框全选
        } else if (this.checkboxDatas.length != 0) {
          document.getElementById('spand').className += ' is-indeterminate' // 设置全选框的半选
        } else {
          document.getElementById('spand').className = 'el-checkbox__input' // 设置全选框未选中状态
        }
      })
      this.$emit('tabSelectChange', this.checkboxDatas)
    },
    // 递归遍历勾选的
    recursiveCheck(row, checked) {
      row.checked = checked
      if (row.children != undefined) {
        row.children.forEach(x => {
          x.checked = checked
          if (x.children != undefined) {
            this.recursiveCheck(x, checked)
          }
        })
      }
    },
    // 动态添加
    addTree(data, id, row, bool) {
      if (data.children != undefined) {
        for (let i = 0; i < data.children.length; i++) {
          if (data.children[i][this.rowKey] == id) {
            data.children.push(row)
            bool = false
            break
          } else {
            this.addTree(data.children[i], id, row, bool)
          }
        }
      }
    },
    // 删除选择的元素
    removerTree(data, id) {
      if (data.children != undefined) {
        for (let i = 0; i < data.children.length; i++) {
          if (data.children[i][this.rowKey] == id) { // 递归到选中的id和表格内子集的id相同  就删除
            data.children.splice(i, 1)
            break
          } else {
            this.removerTree(data.children[i], id)
          }
        }
      }
    },
    // 扁平结构 用于判断
    treeToList(tree) {
      var queen = []
      var out = []
      queen = queen.concat(tree)
      while (queen.length) {
        var first = queen.shift()
        if (first.children != undefined && first.children) {
          queen = queen.concat(first.children)
        }
        out.push(first)
      }
      return out
    },
    // 头部的单选框
    renderHeader(h, data) {
      return h(
        'label',
        {
          attrs: {
            id: 'labels',
            role: 'checkbox',
            class: 'el-checkbox el-text'
          }
        },
        [
          h(
            'span',
            {
              attrs: {
                id: 'spand',
                'aria-checked': 'mixed',
                class: 'el-checkbox__input'
              }
            },
            [
              h('span', {
                attrs: {
                  class: 'el-checkbox__inner'
                }
              }),
              h('input', {
                attrs: {
                  id: 'chooseall',
                  'aria-hidden': 'true',
                  type: 'checkbox',
                  style: 'display: none'
                  /*  style:
                          'border: 1px solid #dcdfe6;border-radius: 2px;box-sizing: border-box;width: 14px;height: 14px;background-color: #fff;'*/
                }
              })
            ]
          )
        ]
      )
    }

  }
}
</script>

<style lang="scss" scoped>
  /deep/.el-text{
    margin-left: 35%;
  }
  /deep/.el-table__indent{
    padding-left: 10px !important;
  }
</style>

效果图
在这里插入图片描述

  • 1
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 22
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 22
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值