实现表格合并

  <template>
    <div class="table-merge-example">
      <h2 class="title">Vue2 表格数据合并示例</h2>
      
      <div class="table-container">
        <h3>横向合并(列合并)</h3>
        <table class="merge-table horizontal-merge">
          <thead>
            <tr>
              <th>数值</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(item, index) in processedHorizontalData" :key="index">
              <td 
                :colspan="item.span" 
                :class="{ 'merged-cell': item.span > 1 }">
                {{ item.value }}
              </td>
            </tr>
          </tbody>
        </table>
      </div>
      
      <div class="table-container">
        <h3>纵向合并(行合并)</h3>
        <table class="merge-table vertical-merge">
          <thead>
            <tr>
              <th>序号</th>
              <th>数值</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(item, index) in originalData" :key="index">
              <td>{{ index + 1 }}</td>
              <td 
                :rowspan="verticalSpans[index]" 
                :class="{ 'merged-cell': verticalSpans[index] > 1 }"
                v-if="verticalSpans[index] > 0">
                {{ item }}
              </td>
            </tr>
          </tbody>
        </table>
      </div>
    </div>
  </template>

  <script>
    export default {
      data() {
        return {
          originalData: [200, 300, 300, 300, 400, 400, 500],
          processedHorizontalData: [],
          verticalSpans: []
        };
      },
    
      mounted() {
        this.processHorizontalMerge();
        this.processVerticalMerge();
      },
    
      methods: {
        // 处理横向合并(列合并)
        processHorizontalMerge() {
          if (this.originalData.length === 0) {return;}
        
          const result = [];
          let currentValue = this.originalData[0];
          let count = 1;
        
          // 从第二个元素开始遍历
          for (let i = 1; i < this.originalData.length; i++) {
            if (this.originalData[i] === currentValue) {
              count++;
            } else {
              // 保存当前组
              result.push({ value: currentValue, span: count });
              // 开始新的一组
              currentValue = this.originalData[i];
              count = 1;
            }
          }
        
          // 添加最后一组
          result.push({ value: currentValue, span: count });
        
          this.processedHorizontalData = result;
        },
      
        // 处理纵向合并(行合并)
        processVerticalMerge() {
          if (this.originalData.length === 0) {return;}
        
          const spans = new Array(this.originalData.length).fill(0);
          let currentValue = this.originalData[0];
          let count = 1;
          spans[0] = 1;
        
          // 从第二个元素开始遍历
          for (let i = 1; i < this.originalData.length; i++) {
            if (this.originalData[i] === currentValue) {
              count++;
              spans[i] = 0; // 被合并的单元格
            } else {
              // 设置上一组的合并数量
              spans[i - count] = count;
              // 开始新的一组
              currentValue = this.originalData[i];
              count = 1;
              spans[i] = 1;
            }
          }
        
          // 设置最后一组的合并数量
          spans[this.originalData.length - count] = count;
        
          this.verticalSpans = spans;
        }
      }
    };
  </script>

  <style scoped>
  .table-merge-example {
    max-width: 800px;
    margin: 20px auto;
    padding: 20px;
    font-family: Arial, sans-serif;
  }

  .title {
    text-align: center;
    color: #333;
    margin-bottom: 30px;
  }

  .table-container {
    margin-bottom: 40px;
    border: 1px solid #e0e0e0;
    border-radius: 6px;
    padding: 15px;
    box-shadow: 0 2px 4px rgba(0,0,0,0.1);
  }

  .table-container h3 {
    color: #444;
    margin-top: 0;
    margin-bottom: 15px;
    padding-bottom: 10px;
    border-bottom: 1px solid #eee;
  }

  .merge-table {
    width: 100%;
    border-collapse: collapse;
    text-align: center;
  }

  .merge-table th,
  .merge-table td {
    padding: 12px 15px;
    border: 1px solid #ddd;
  }

  .merge-table th {
    background-color: #f5f5f5;
    font-weight: bold;
    color: #555;
  }

  .merge-table tr:nth-child(even) {
    background-color: #f9f9f9;
  }

  .merge-table tr:hover {
    background-color: #f0f7ff;
  }

  .merged-cell {
    background-color: #e6f7ff;
    font-weight: bold;
    color: #1890ff;
  }

  .horizontal-merge td {
    border-right: 2px solid #fff;
  }

  .vertical-merge td {
    border-bottom: 2px solid #fff;
  }
  </style>
posted @ 2025-11-11 10:16  不完美的完美  阅读(3)  评论(0)    收藏  举报