el-table动态实现行合并

102 阅读1分钟

效果图:

1743406253591.jpg 完整代码如下:

<template>
  <el-table
    class="list"
    :data="detailList"
    :span-method="arraySpanMethod"
    border
  >
    <el-table-column prop="evaluateItemName" align="center" min-width="50">
      <span slot="header">日期 </span>
      <template slot-scope="scope">
        <span>{{ scope.row.evaluateItemName }}</span>
      </template>
    </el-table-column>
    <el-table-column prop="evaluateContent" align="center" min-width="50">
      <span slot="header">时间 </span>
      <template slot-scope="scope">
        <span>{{ scope.row.evaluateContent }}</span>
      </template>
    </el-table-column>
    <el-table-column prop="evaluateDescribe" align="center" min-width="50">
      <span slot="header"> 科目 </span>
      <template slot-scope="scope">
        <span>{{ scope.row.evaluateDescribe }}</span>
      </template>
    </el-table-column>
    <el-table-column prop="score" align="center">
      <span slot="header"> <span class="required">*</span>分数 </span>
      <template slot-scope="scope">
        <el-input-number
          v-model="scope.row.score"
          placeholder="请输入"
          :min="0"
          :max="100"
          :precision="2"
        />
      </template>
    </el-table-column>
  </el-table>
</template>
<script>
export default {
  data() {
    return {
      detailList: [
        {
          evaluateItemName: '周一',
          evaluateContent: '8:00-9:30',
          score: undefined,
          evaluateDescribe: '数学'
        },
        {
          evaluateItemName: '周一',
          evaluateContent: '9:45-11:15',
          score: undefined,
          evaluateDescribe: '物理'
        },
        {
          evaluateItemName: '周一',
          evaluateContent: '13:00-14:30',
          score: undefined,
          evaluateDescribe: '历史'
        },
        {
          evaluateItemName: '周二',
          evaluateContent: '8:00-9:30',
          score: undefined,
          evaluateDescribe: '物理'
        }
      ],
      spanArr: [], // 用于存放每一行记录的合并数
      pos: 0
    }
  },
  mounted() {
    this.getSpanArr(this.detailList)
  },
  methods: {
    arraySpanMethod({ row, column, rowIndex, columnIndex }) {
      if (columnIndex === 0) {
        const _row = this.spanArr[rowIndex]
        const _col = _row > 0 ? 1 : 0
        return {
          rowspan: _row,
          colspan: _col
        }
      }
    },
    getSpanArr(data) {
      for (var i = 0; i < data.length; i++) {
        if (i === 0) {
          this.spanArr.push(1)
          this.pos = 0
        } else {
          // 判断当前元素与上一个元素是否相同
          if (data[i].evaluateItemName === data[i - 1].evaluateItemName) {
            this.spanArr[this.pos] += 1
            this.spanArr.push(0)
          } else {
            this.spanArr.push(1)
            this.pos = i
          }
        }
      }
    }
  }
}
</script>
<style scoped>
.list {
  width: 90%;
  margin: 5% auto;
}
.required {
  color: red;
}
::v-deep .el-input-number {
  width: 95%;
}
</style>