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

要实现的需求是这样的:
在这里插入图片描述
本来我是用 el-table 的 :span-method 方法实现的,但发现合并起来有问题,跟我的需求差距有些大,于是我想到了嵌套表格。但是嵌套完之后的样子也是很奇怪:
在这里插入图片描述
不要气馁,思路还是对的,只要改下样式就好了,于是就有了以下的代码:

<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 中再套一个 el-table,但重点是子表格不要显示表头,而且样式要自己写,尤其是要通过 :render-header 重写表格样式。这里只是粗略实现了样式,需要的同学自行优化样式。

### 实现 Element UI 中 el-table 组件内部嵌套另一个 el-table 为了实现在 `el-table` 组件中嵌套另一个 `el-table`,可以采用自定义模板的方式,在父级表格的某一列中渲染子表格。具体实现如下: #### HTML 结构 ```html <template> <div> <!-- 外层表格 --> <el-table :data="outerTableData"> <el-table-column prop="name" label="外层表头"></el-table-column> <!-- 自定义列用于显示内层表格 --> <el-table-column label="详情"> <template slot-scope="scope"> <!-- 内层表格 --> <el-table v-if="showInner(scope.row)" :data="innerTableData[scope.$index]" style="width: 100%"> <el-table-column prop="detailName" label="内层表头"></el-table-column> <el-table-column prop="value" label="数值"></el-table-column> </el-table> </template> </el-table-column> </el-table> </div> </template> ``` #### JavaScript 部分 ```javascript <script> export default { data() { return { outerTableData: [ { name: "项目A", details: [{ detailName: "任务1", value: 10 }] }, { name: "项目B", details: [{ detailName: "任务2", value: 20 }, { detailName: "任务3", value: 30 }] } ], innerTableData: [] }; }, methods: { showInner(row) { this.innerTableData[row.index] = row.details; return true; // 控制是否显示内层表格 } }, created() { // 初始化时处理数据映射关系 this.outerTableData.forEach((item, index) => { this.$set(this.innerTableData, index, item.details); }); } }; </script> ``` 上述代码展示了如何在外层表格的一列里放置一个条件性的内层表格[^1]。 #### 关键点说明 - 使用 `<template>` 标签结合 `slot-scope` 属性来创建作用域插槽,从而允许访问当前行的数据。 - 利用 `v-if` 来控制何时渲染内层表格,防止不必要的重绘和性能损耗。 - 数据绑定方面,通过计算属性或方法动态调整内外两层表格之间的关联逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

代码搬运媛

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值