直接上代码

HTML 部分代码

<el-table
      :data="dataList"
      isBigData
      element-loading-text="数据正在加载中......"
      max-height="1200"
      istable
      default-expand-all  //默认展开
      size="medium"
      @selection-change="selectionChangeHandle"  //选择项发生变化时会触发该事件
      v-loading="loading"
      row-key="id"
      class="table canClickTable"
      ref="product"
      :row-class-name="rowClassNameFun" //行的 className 的回调方法
      :header-row-class-name="headerRowClassName"  //表头行的 className 的回调方法
      @select="selectFun"  //用户手动勾选数据行的 Checkbox 时触发的事件
      @select-all="selectAllFun" // 用户手动勾选全选 
    >
      <el-table-column
        type="selection"
        header-align="center"
        align="center"
        min-width="50"
      >
      </el-table-column>
      <el-table-column
        prop="name"
        align="left"
        show-overflow-tooltip
        min-width="350"
        label="考核项目"
      >
      </el-table-column>
      <el-table-column
        prop="deductPoints"
        show-overflow-tooltip
        min-width="150"
        label="单次扣分"
      >
        <template slot-scope="scope">
          <span v-if="scope.row.deductPoints != '0'">{{
            scope.row.deductPoints
          }}</span>
        </template>
      </el-table-column>
      <el-table-column
        prop="deductPointsLimit"
        show-overflow-tooltip
        min-width="150"
        label="扣分上限"
      >
        <template slot-scope="scope">
          <span v-if="scope.row.deductPointsLimit != '0'">{{
            scope.row.deductPointsLimit
          }}</span>
        </template>
      </el-table-column>
      <el-table-column
        header-align="center"
        align="center"
        fixed="right"
        min-width="150"
        label="操作"
      >
        <template slot-scope="scope">
          <el-button type="text" size="small" @click="edit(scope.row)"
            >编辑</el-button
          >
          <el-button
            v-if="scope.row.parentId == '0'"
            type="text"
            size="small"
            @click="addChild(scope.row.id)"
            >添加下级</el-button
          >
        </template>
      </el-table-column>
    </el-table>

vue methods 方法代码

//初始化数据 给所有数据加上 isSelect  false 默认都为不选中状态  获取接口的列表数据的时候调用这个方法
initData(data) {
      data.forEach((item) => {
        item.isSelect = false; //默认为不选中
        if (item.children && item.children.length) {
          this.initData(item.children);
        }
      });
    },
//勾选 触发
selectFun(selection, row) {
      this.setRowIsSelect(row);
    },
    setRowIsSelect(row) {
      //当点击父级点复选框时,当前的状态可能为未知状态,所以当前行状态设为false并选中,即可实现子级点全选效果
      if (row.isSelect === "") {
        row.isSelect = false;
        this.$refs.product.toggleRowSelection(row, true);
      }
      row.isSelect = !row.isSelect;
      let that = this;

      function selectAllChildrens(data) {
        data.forEach((item) => {
          item.isSelect = row.isSelect;
          that.$refs.product.toggleRowSelection(item, row.isSelect);
          if (item.children && item.children.length) {
            selectAllChildrens(item.children);
          }
        });
      }

      function getSelectStatus(selectStatuaArr, data) {
        data.forEach((childrenItem) => {
          selectStatuaArr.push(childrenItem.isSelect);
          if (childrenItem.children && childrenItem.children.length) {
            getSelectStatus(selectStatuaArr, childrenItem.children);
          }
        });
        return selectStatuaArr;
      }
      function getLevelStatus(row) {
        //如果当前节点的parantId =0 并且有子节点,则为1
        //如果当前节点的parantId !=0 并且子节点没有子节点 则为3
        if (row.parentId == 0) {
          if (row.children && row.children.length) {
            return 1;
          } else {
            return 4;
          }
        } else {
          if (!row.children || !row.children.length) {
            return 3;
          } else {
            return 2;
          }
        }
      }
      let result = {};
      //获取明确的节点
      function getExplicitNode(data, parentId) {
        data.forEach((item) => {
          if (item.id == parentId) {
            result = item;
          }
          if (item.children && item.children.length) {
            getExplicitNode(item.children, parentId);
          }
        });
        return result;
      }
      function operateLastLeve(row) {
        //操作的是子节点  1、获取父节点  2、判断子节点选中个数,如果全部选中则父节点设为选中状态,如果都不选中,则为不选中状态,如果部分选择,则设为不明确状态
        let selectStatuaArr = [];
        let item = getExplicitNode(that.dataList, row.parentId);
        selectStatuaArr = getSelectStatus(selectStatuaArr, item.children);
        if (
          selectStatuaArr.every((selectItem) => {
            return true == selectItem;
          })
        ) {
          item.isSelect = true;
          that.$refs.product.toggleRowSelection(item, true);
        } else if (
          selectStatuaArr.every((selectItem) => {
            return false == selectItem;
          })
        ) {
          item.isSelect = false;
          that.$refs.product.toggleRowSelection(item, false);
        } else {
          item.isSelect = "";
        }
        //则还有父级
        if (item.parentId != 0) {
          operateLastLeve(item);
        }
      }
      //判断操作的是子级点复选框还是父级点复选框,如果是父级点,则控制子级点的全选和不全选

      //1、只是父级 2、既是子集,又是父级 3、只是子级
      let levelSataus = getLevelStatus(row);
      if (levelSataus == 1) {
        selectAllChildrens(row.children);
      } else if (levelSataus == 2) {
        selectAllChildrens(row.children);
        operateLastLeve(row);
      } else if (levelSataus == 3) {
        operateLastLeve(row);
      }
    },
    checkIsAllSelect() {
      this.oneProductIsSelect = [];
      this.dataList.forEach((item) => {
        this.oneProductIsSelect.push(item.isSelect);
      });
      //判断一级产品是否是全选.如果一级产品全为true,则设置为取消全选,否则全选
      let isAllSelect = this.oneProductIsSelect.every((selectStatusItem) => {
        return true == selectStatusItem;
      });
      return isAllSelect;
    },
    selectAllFun(selection) {
      let isAllSelect = this.checkIsAllSelect();
      this.dataList.forEach((item) => {
        item.isSelect = isAllSelect;
        this.$refs.product.toggleRowSelection(item, !isAllSelect);
        this.selectFun(selection, item);
      });
    },
    rowClassNameFun({ row }) {
      if (row.isSelect === "") {
        return "indeterminate";
      }
    },
    headerRowClassName({ row }) {
      let oneProductIsSelect = [];
      this.dataList.forEach((item) => {
        oneProductIsSelect.push(item.isSelect);
      });
      if (oneProductIsSelect.includes("")) {
        return "indeterminate";
      }
      return "";
    },

   // 多选 删除 或者获取选中的 数据 
   selectionChangeHandle() {
      this.checkData(this.dataList);
      this.allSelections = [
        ...this.selectionsParent,
        ...this.selectionsChildren,
        ...this.checkSelectionsParent,
      ];
    },
    checkData(data) {
      var newData = data;
      this.selectionsParent = [];
      this.selectionsChildren = [];
      this.checkSelectionsParent = [];
      if (newData.length > 0) {
        for (var i = 0; i < newData.length; i++) {
          if (newData[i].isSelect) {
            this.selectionsParent.push(newData[i]);
          } else {
            this.checkSelectionsParent.push(newData[i]);
          }
          if (newData[i].children && newData[i].children.length > 0) {
            for (var j = 0; j < newData[i].children.length; j++) {
              if (newData[i].children[j].isSelect) {
                this.selectionsChildren.push(newData[i].children[j]);
              }
            }
          }
        }
      }
    },

css样式代码 实现半选样式等

<style scoped lang="scss">
.indeterminate .el-checkbox__input .el-checkbox__inner {
  background-color: #409eff !important;
  border-color: #409eff !important;
  color: #fff !important;
}

.indeterminate .el-checkbox__input.is-checked .el-checkbox__inner::after {
  transform: scale(0.5);
}

.indeterminate .el-checkbox__input .el-checkbox__inner {
  background-color: #f2f6fc;
  border-color: #dcdfe6;
}
.indeterminate .el-checkbox__input .el-checkbox__inner::after {
  border-color: #c0c4cc !important;
  background-color: #c0c4cc;
}
.product-show th .el-checkbox__inner {
  display: none !important;
}

.indeterminate .el-checkbox__input .el-checkbox__inner::after {
  content: "";
  position: absolute;
  display: block;
  background-color: #fff;
  height: 2px;
  transform: scale(0.5);
  left: 0;
  right: 0;
  top: 5px;
  width: auto !important;
}
.product-show .el-checkbox__inner {
  display: block !important;
}

.product-show .el-checkbox {
  display: block !important;
}
</style>

注:部分代码是参考其他博主代码 作为改动  如有侵权 请联系删除^_^

写的有些复杂 但是可以实现需求  如果有更好的方法 欢迎留言  Thanks♪(・ω・)ノ

Logo

前往低代码交流专区

更多推荐