element 横向重复 纵向分类

<template>
  <div>
    <el-table
      :data="tableData"
      border
      style="width: 100%"
      :span-method="objectSpanMethod"
    >
      <el-table-column prop="category" label="分类" width="120" />
      <el-table-column prop="product1" label="名称" width="120" />
      <el-table-column prop="count1" label="用量" width="80" />
      <el-table-column prop="product2" label="名称" width="120" />
      <el-table-column prop="count2" label="用量" width="80" />
      <el-table-column prop="product3" label="名称" width="120" />
      <el-table-column prop="count3" label="用量" width="80" />
    </el-table>
  </div>
</template>

<script>
export default {
  data() {
    return {
      // 原始扁平数据
      rawData: [
        { category: '食品', product: '苹果', count: 10 },
        { category: '食品', product: '香蕉', count: 15 },
        { category: '食品', product: '橙子', count: 8 },
        { category: '食品', product: '梨子', count: 12 },
        { category: '食品', product: '西瓜', count: 56 },
        { category: '食品', product: '榴莲', count: 56 },
        { category: '食品', product: '草莓', count: 56 },
        { category: '饮料', product: '可乐', count: 20 },
        { category: '饮料', product: '雪碧', count: 18 },
        { category: '日用品', product: '牙刷', count: 5 },
        { category: '日用品', product: '牙膏', count: 7 },
        { category: '日用品', product: '毛巾', count: 3 },
      ],
      tableData: [], // 处理后的表格数据
      spanArr: [], // 用于合并行的数组
    }
  },
  created() {
    this.processData();
  },
  methods: {
    // 处理原始数据
    processData() {
      const categoryMap = {};
      
      // 按分类分组
      this.rawData.forEach(item => {
        if (!categoryMap[item.category]) {
          categoryMap[item.category] = [];
        }
        categoryMap[item.category].push(item);
      });
      
      // 生成表格数据
      this.tableData = [];
      this.spanArr = [];
      
      Object.keys(categoryMap).forEach(category => {
        const items = categoryMap[category];
        const rowCount = Math.ceil(items.length / 3); // 计算需要多少行
        
        for (let i = 0; i < rowCount; i++) {
          const startIdx = i * 3;
          const endIdx = startIdx + 3;
          const rowItems = items.slice(startIdx, endIdx);
          
          const row = { category: i === 0 ? category : '' };
          
          // 填充三组数据
          rowItems.forEach((item, idx) => {
            row[`product${idx + 1}`] = item.product;
            row[`count${idx + 1}`] = item.count;
          });
          
          // 填充剩余的空列
          for (let j = rowItems.length; j < 3; j++) {
            row[`product${j + 1}`] = '';
            row[`count${j + 1}`] = '';
          }
          
          this.tableData.push(row);
        }
        
        // 记录合并信息
        this.spanArr.push({
          category,
          rowCount
        });
      });
    },
    
    // 合并行的方法
    objectSpanMethod({ row, column, rowIndex, columnIndex }) {
      if (columnIndex === 0) { // 处理分类列
        for (let i = 0; i < this.spanArr.length; i++) {
          const group = this.spanArr[i];
          const start = i === 0 ? 0 : this.spanArr.slice(0, i).reduce((sum, g) => sum + g.rowCount, 0);
          
          if (rowIndex >= start && rowIndex < start + group.rowCount) {
            if (rowIndex === start) {
              return {
                rowspan: group.rowCount,
                colspan: 1
              };
            } else {
              return {
                rowspan: 0,
                colspan: 0
              };
            }
          }
        }
      }
    }
  }
}
</script>

<style>
.el-table .cell {
  white-space: nowrap;
}
</style>
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容