ElementuUI el-table 树型表格 checkbox多选框选择逻辑

ElementuUI el-table 树型表格 checkbox多选框选择逻辑

如图所示:
ElementuUI el-table 树型表格 checkbox多选框选择逻辑_第1张图片

逻辑:

子节点全部选择 => 父节点选择
子节点部分选择 => 父节点半选择
子节点全未选择 => 父节点不选择

代码部分如下:
<template>
  <div class="container">
    <el-table
          :data="tableData"
          border
          style="width: 100%"
          row-key="id"
          default-expand-all
          :tree-props="{ children: 'children' ,hasChildren: 'children.length>0'}"
          ref="tableRef"
          @select="handletableSelect"
          @select-all="handletableSelectAll"
          @selection-change="handletableSelectionChange">
          
         
         <el-table-column
            type="selection"/>
 	     
         <el-table-column
            prop="id"
            label="id"
          >el-table-column>

		 
		 
    el-table>
  div>
template>

<script>
export default {
  name: "TreeTableCheckbox",
  data() {
    return {
      tableData: [
        {
          id: 1,
          date: '2016-05-02',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1518 弄'
        }, {
          id: 2,
          date: '2016-05-04',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1517 弄'
        }, {
          id: 3,
          date: '2016-05-01',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1519 弄',
          children: [
            {
            id: 31,
            date: '2016-05-01',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1519 弄'
          }, {
            id: 32,
            date: '2016-05-01',
            name: '王小虎',
            address: '上海市普陀区金沙江路 1519 弄'
          }
          ]
        }, {
          id: 4,
          date: '2016-05-03',
          name: '王小虎',
          address: '上海市普陀区金沙江路 1516 弄'
        }
      ]
      tableSelect: [],
    }
  },
  methods: {
    // 当用户手动勾选数据行的 Checkbox 时触发的事件
    handletableSelect(selection, row) {
      if (row.children) { //只对有子节点的行响应
        // if (row.isChecked === undefined) row.isChecked = true
        if (!row.isChecked) {   //由行数据中的元素isChecked判断当前是否被选中
          this.traverseChildNodes(row.children, this.$refs.tableRef, true)
          row.isChecked = true; //当前行isChecked标志元素切换为false
        } else {
          this.traverseChildNodes(row.children, this.$refs.tableRef, false)
          row.isChecked = false;
        }
      }
      // 处理父级选择逻辑
      // tableSelect 字段是 handletableSelectionChange 回调回来的
      // 如果不用 this.$nextTick 无法获取到正确数据
      this.$nextTick(() => {
        // 递归寻找当前子节点的父级节点
        let getParentNode = function (data, id) {
          for (let i in data) {
            if (data.hasOwnProperty(i)) {
              if (data[i].id === id) {
                return [data[i]]
              }
              if (data[i].children) {
                let node = getParentNode(data[i].children, id);
                if (node !== undefined) {
                  return node.concat(data[i])
                }
              }
            }
          }
        }
        // 设置checkbox半选择状态
        // 此处的传入的id就是匹配表格id字段的
        let updateCheckboxIndeterminate = function (id, isIndeterminate) {
          setTimeout(() => {
            // el-table不支持checkbox半选 目前方案是遍历dom获取行节点设置样式
            let elementsRow = document.getElementsByClassName("el-table__row");
            for (let i = 0; i < elementsRow.length; i++) {
              let element = elementsRow.item(i);
              // tips: 通过其他手段设置行内row-id的 以下代码需要修改
              let childNode = element.childNodes.item(1); // row-key 字段在dom中的索引   第二列=1
              if (childNode.innerText === `${id}`) {
                let td = element.childNodes.item(0) // 获取要设置半选中状态的checkbox
                let div = td.firstChild; // 
let label = div.firstChild; // let span = label.firstChild; // if (isIndeterminate) span.classList.add("is-indeterminate") // 设置半选中状态 else span.classList.remove("is-indeterminate") // 取消半选中状态 } } }, 1) } let parentNode = getParentNode(this.$refs.tableRef.data, row.id) // > 1 说明节点有子节点 if (parentNode.length > 1) { // 提取兄弟节点ids let siblingNodeIds = parentNode[1].children.map(item => item.id) // 提取全选所选择项的ids let checkedIds = this.tableSelect.map(item => item.id) // 获取兄弟行选择数 let siblingNodeCheckedIds = siblingNodeIds.filter(id => checkedIds.indexOf(id) !== -1) if (siblingNodeCheckedIds.length === siblingNodeIds.length) { // 兄弟节点选择数===兄弟节点数 全选 updateCheckboxIndeterminate(parentNode[1].id, false) parentNode[1].isChecked = true this.$refs.tableRef.toggleRowSelection(parentNode[1], true) } else if (siblingNodeCheckedIds.length === 0) { // 兄弟节点选择数===0 全不选 parentNode[1].isChecked = false this.$refs.tableRef.toggleRowSelection(parentNode[1], false) updateCheckboxIndeterminate(parentNode[1].id, false) } else if (siblingNodeCheckedIds.length < siblingNodeIds.length) { parentNode[1].isChecked = true this.$refs.tableRef.toggleRowSelection(parentNode[1], true) for (let i = 0; i < parentNode.length; i++) { if (i > 0) updateCheckboxIndeterminate(parentNode[i].id, true) } } } }) }, // 当用户手动勾选全选 Checkbox 时触发的事件 handletableSelectAll(selection) { this.$refs.tableRef.data.map(items => { if (items.children && items.children.length > 0) { if (!items.isChecked) { this.$refs.tableRef.toggleRowSelection(items, true); items.isChecked = true this.traverseChildNodes(items.children, this.$refs.tableRef, true) } else { this.$refs.tableRef.toggleRowSelection(items, false); items.isChecked = false; this.traverseChildNodes(items.children, this.$refs.tableRef, false) } } else { items.isChecked = !items.isChecked; } }) }, // 当选择项发生变化时会触发该事件 handletableSelectionChange(selection) { this.tableSelect = selection }, // 递归设置子节点 traverseChildNodes(children, ref, selected) { children.map(item => { ref.toggleRowSelection(item, selected); item.isChecked = selected; if (item.children) { this.traverseChildNodes(item.children, ref, selected) } }) }, }, } script> <style scoped> style>

可能有更好的实现逻辑,欢迎交流。

你可能感兴趣的:(elementui,vue.js)