要实现的需求是这样的:

el-table 实现嵌套表格的思路及完整功能代码_elementui


本来我是用 el-table 的 :span-method 方法实现的,但发现合并起来有问题,跟我的需求差距有些大,于是我想到了嵌套表格。但是嵌套完之后的样子也是很奇怪:

el-table 实现嵌套表格的思路及完整功能代码_vue.js_02


不要气馁,思路还是对的,只要改下样式就好了,于是就有了以下的代码:

<template>
  <el-table
    border
    :data="tableData"
    v-loading="loading"
    class="el-child-table"
  >
    <el-table-column
      prop="applyDate"
      label="申请日期"
      align="center"
      width="120px"
    >
    </el-table-column>
    <el-table-column
      prop="table"
      label="子表"
      class-name="has-child"
      :render-header="renderHeader"
    >
      <template slot-scope="scope">
        <el-table
          
          :data="scope.row.details"
          class="child-table"
          :show-header="false"
        >
        <el-table-column
            prop="startDate"
            align="center"
            label="开始日期"
            width="120px"
          ></el-table-column>
          <el-table-column
            prop="endDate"
            align="center"
            label="结束日期"
            width="120px"
          ></el-table-column>
          <el-table-column
            prop="applyDay"
            align="center"
            label="申请天数"
            width="120px"
          ></el-table-column> 
           <el-table-column label="操作" align="center" width="220px">
            <el-button type="text" @click="viewItem(scope.row)">查看</el-button>
          </el-table-column> 
        </el-table>
      </template>
    </el-table-column>
    
  </el-table>
</template>

<script>
export default {
  data() {
    return {
      loading: false,
      childColumn: [
        {
          label: "起始日期",
          key: 'startDate',
          width: "120px",
        },
        {
          label: "结束日期",
          key: 'endDate',
          width: "120px",
        },
        {
          label: "申请天数",
          key: 'applyDay',
          width: "120px",
        },
        {
          label: "操作",
          width: "220px",
        }
      ],
      tableData: [
        {
          applyDate: '2016-05-02',
          details: [
          {
            startDate: '2016-05-02',
            endDate: '2016-05-02',
            applyDay: 5
          },{
            startDate: '2016-05-02',
            endDate: '2016-05-02',
            applyDay: 5
          }
          ]
        },
        {
          applyDate: '2016-05-02',
          details: [
          {
            startDate: '2016-05-02',
            endDate: '2016-05-02',
            applyDay: 5
          },{
            startDate: '2016-05-02',
            endDate: '2016-05-02',
            applyDay: 5
          }
          ]
        },{
          applyDate: '2016-05-02',
          details: [
          {
            startDate: '2016-05-02',
            endDate: '2016-05-02',
            applyDay: 5
          },{
            startDate: '2016-05-02',
            endDate: '2016-05-02',
            applyDay: 5
          }
          ]
        }
      ]
    };
  },
  methods: {
    renderHeader(h, { column, $index }) {
      const childTable = this.childColumn.map((item) => {
        return h(
          "div",
          {
            style: {
              width: item.width,
              padding: "0 10px",
              textAlign: "center",
              flexShrink: 0,
              flexGrow: 0,
            },
          },
          item.label
        );
      });
      return h(
        "div",
        {
            style: {
              display: 'flex'
            },
          },
      
        childTable
      );
    },
    viewItem(row){}
  }
}
</script>

<style scoped lang="scss">
.has-child {
  padding: 0px !important;
  // display: none;
  & > .cell {
    padding: 0 !important;
  }
  ::before {
    height: 0;
  }
  .child-table {
    background-color: transparent;
    .cell{
      line-height: 34px;
    }
  }
  .el-table--enable-row-hover .el-table__body tr:hover > td.el-table__cell {
    background-color: transparent;
  }
  .el-table__body tr.current-row > td.el-table__cell,
  .el-table__body tr.selection-row > td.el-table__cell {
    background-color: transparent;
  }
  tr {
    background-color: transparent;
  }
  .child-head {
    display: flex!important;
  }
  ::v-deep .el-table .el-table__cell{
    padding: 0;
  }
  ::v-deep .el-table .cell{
    line-height: 34px;
  }
}
</style>

总算功夫不负有心人,最终效果还是让我实现了。

el-table 实现嵌套表格的思路及完整功能代码_vue.js_03

总结知识点

这里总结以下要点啊,
首先嵌套就是 el-table 中再套一个 el-table,但重点是子表格不要显示表头,而且样式要自己写,尤其是要通过 :render-header 重写表格样式。这里只是粗略实现了样式,需要的同学自行优化样式。