ElementUI 中 Table 嵌套另一个 Table,多选嵌套多选

10,739 阅读1分钟

◆ 效果图

image

◆ 核心原理

    1. table 如何嵌套 table

<el-table-column>中的<template>里面直接嵌套<table>,内容就是props.row.childList

<el-table-column type="expand">
  <template slot-scope="props">
    <el-table :data="props.row.childList"/>
    1. 复选框如何嵌套复选框

不要用table自带的type="selection",所有的复选框都自己写


<el-table-column width="50" align="center">
  <!-- 头部的全选按钮,最大的全选 -->
  <div slot="header" slot-scope="scope">
    <el-checkbox
      v-model="globelCheckedAll"
      @change="clickCheckAll(scope)"
      :indeterminate="isIndeterminateAll"
    ></el-checkbox>
  </div>
  <!-- 每一项的选择框,全选子元素 -->
  <template slot-scope="scope">
    <el-checkbox
      v-model="scope.row.isChecked"
      :indeterminate="scope.row.isIndeterminate"
      @change="handleSelectionChange(scope.row)"
    ></el-checkbox>
  </template>
</el-table-column>
<el-table-column align="center" type="expand">
  <template slot-scope="props">
    <!-- 展开内容表 -->
    <el-table
      :data="props.row.childList"
      style="width: 100%"
      class="child-table"
      row-key="guid"
    >
      <el-table-column label="选择" width="120" align="center">
      <!-- 子元素的选择框 -->
        <template slot-scope="scope">
          <el-checkbox
            v-model="scope.row.isChecked"
            @change="clickCheckItemFn(props.row, scope.row)"
          ></el-checkbox>
        </template>
      </el-table-column>

      ...

    </el-table>
  </template>
</el-table-column>

...


data() {
  return {
    isIndeterminateAll: false,
    globelCheckedAll: false,
    tableData: []
  }
},
mounted() {
  this.initData()
},
methods: {
  initData() {
    for (let index = 0; index < 11; index++) {
      this.tableData.push({
        id: index + 1,
        isChecked: false,
        isIndeterminate: false,
        childList: [
          {
            lastTime: '2021/3/2 12:00',
            isChecked: false
          },
          {
            lastTime: '2021/3/2 12:00',
            isChecked: false
          }
        ]
      })
    }
  },
}

◆ 源码

<template>
  <page-box title="test">
    <div slot="box" class="issued-manage">
      <!-- 数据表 -->
      <el-table
        border
        :data="tableData"
        class="issued-list"
        height="100%"
        style="width: 100%"
      >
        <el-table-column width="50" align="center">
          <div slot="header" slot-scope="scope">
            <el-checkbox
              v-model="globelCheckedAll"
              @change="clickCheckAll(scope)"
              :indeterminate="isIndeterminateAll"
            ></el-checkbox>
          </div>
          <template slot-scope="scope">
            <el-checkbox
              v-model="scope.row.isChecked"
              :indeterminate="scope.row.isIndeterminate"
              @change="handleSelectionChange(scope.row)"
            ></el-checkbox>
          </template>
        </el-table-column>
        <el-table-column align="center" type="expand">
          <template slot-scope="props">
            <!-- 展开内容表 -->
            <el-table
              :data="props.row.childList"
              style="width: 100%"
              class="child-table"
              row-key="guid"
            >
              <el-table-column label="选择" width="120" align="center">
                <template slot-scope="scope">
                  <el-checkbox
                    v-model="scope.row.isChecked"
                    @change="clickCheckItemFn(props.row, scope.row)"
                  ></el-checkbox>
                </template>
              </el-table-column>
              <el-table-column prop="auto" label="通行授权" />
              <el-table-column prop="status" label="下发状态" />
              <el-table-column prop="lastTime" label="最后下发时间" />
              <el-table-column label="操作">
                <template slot-scope="scope">
                  <div class="operat-box">
                    <i
                      class="icon icon-del"
                      @click="
                        clickDelFn(
                          props.row,
                          props.$index,
                          scope.row,
                          scope.$index
                        )
                      "
                    >删除</i>
                  </div>
                </template>
              </el-table-column>
            </el-table>
          </template>
        </el-table-column>
        <el-table-column label="序号" prop="id" width="60"></el-table-column>
        <el-table-column label="头像" width="60">
          <template slot-scope="scope">
            <img :src="scope.row.image" class="avator-img" alt="" srcset="" />
          </template>
        </el-table-column>
        <el-table-column label="姓名" prop="name"></el-table-column>
        <el-table-column label="联系方式" prop="tel"></el-table-column>
        <el-table-column label="所属单位" prop="unit"></el-table-column>
        <el-table-column label="人员类型" prop="type"></el-table-column>
        <el-table-column label="录入时间" prop="time"></el-table-column>
      </el-table>
    </div>
  </page-box>
</template>
<script>
export default {
  data() {
    return {
      isIndeterminateAll: false,
      globelCheckedAll: false,
      tableData: []
    }
  },
  mounted() {
    this.initData()
  },
  methods: {
    initData() {
      for (let index = 0; index < 11; index++) {
        this.tableData.push({
          id: index + 1,
          name: '张三',
          tel: '18111778899',
          unit: '公司A-部门C-部门C1',
          image:
            'https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=2974063438,76061761&fm=26&gp=0.jpg',
          type: '员工',
          time: '2021/2/2712:00',
          isChecked: false,
          isIndeterminate: false,
          childList: [
            {
              guid: 'xx97',
              auto: '高区出入口',
              status: '未下发',
              lastTime: '2021/3/2 12:00',
              isChecked: false
            },
            {
              guid: 'xx98',
              auto: '高区出入口',
              status: '未下发',
              lastTime: '2021/3/2 12:00',
              isChecked: false
            }
          ]
        })
      }
    },
    // 手动更改全选按钮的状态
    updateCheckedAllBtnStatus(value) {
      // 如果是选了勾选
      if (value) {
        // 检查是否所有数据都手动勾选了
        let isAllChecked = this.tableData.every(v => v.isChecked)
        if (isAllChecked) {
          this.globelCheckedAll = true
          this.isIndeterminateAll = false
        } else {
          this.isIndeterminateAll = true
        }
      } else {
        // 检查是否所有数据取消勾选了
        let isAllCancelChecked = this.tableData.every(v => v.isChecked == false)
        if (isAllCancelChecked) {
          this.globelCheckedAll = false
          this.isIndeterminateAll = false
        } else {
          this.isIndeterminateAll = true
        }
      }
    },
    // 全选所有
    clickCheckAll(item) {
      // 此处console的item无效,仅为了eslint校验,而slot-scope="scope"又是必传
      console.log(item)
      this.tableData = this.tableData.map(val => {
        val.isChecked = this.globelCheckedAll
        val.childList = val.childList.map(i => {
          i.isChecked = this.globelCheckedAll
          return i
        })
        return val
      })
      this.updateCheckedAllBtnStatus(this.globelCheckedAll)
    },
    // 每行选择事件
    handleSelectionChange(val) {
      val.childList = val.childList.map(i => {
        i.isChecked = val.isChecked
        return i
      })
      val.isIndeterminate = false
      this.updateCheckedAllBtnStatus(val.isChecked)
    },

    // 每个小项选择事件-单选
    clickCheckItemFn(row, item) {
      // 如果是选了勾选
      if (item.isChecked) {
        this.isIndeterminateAll = true
        // 检查是否所有数据都手动勾选了
        let isAllChecked = row.childList.every(v => v.isChecked)
        if (isAllChecked) {
          row.isChecked = true
          row.isIndeterminate = false
        } else {
          row.isIndeterminate = true
        }
      } else {
        // 检查是否所有数据取消勾选了
        let isAllCancelChecked = row.childList.every(v => v.isChecked == false)
        if (isAllCancelChecked) {
          row.isChecked = false
          row.isIndeterminate = false
          this.isIndeterminateAll = false
        } else {
          row.isIndeterminate = true
        }
      }
    },

    // 单项操作-删除
    clickDelFn(row, index, item, itemIndex) {
      console.log(row, index, item, itemIndex)
    }
  }
}
</script>

<style lang="scss" scoped>
img{
  width:50px;
  height: 50px;
}
</style>