Write a table to simulate some data:

mergeTable.vue :

<template>
  <div style="width:800px">
    <el-table :data="tableData" stripe border :span-method="arraySpanMethod">
      <el-table-column prop="class" label="Class"></el-table-column>
      <el-table-column prop="name" label="Name"></el-table-column>
      <el-table-column prop="course" label="Subject"></el-table-column>
      <el-table-column prop="score" label="Performance"></el-table-column>
    </el-table>
  </div>
</template>
Copy the code

Data preparation:

tableData: [
        {
          class: "class1",
          name: "Wang Xiaohu",
          course: "English",
          score: "88"
        },
        {
          class: "class1",
          name: "Wang Xiaohu",
          course: "Chinese",
          score: "90"
        },
        {
          class: "class1",
          name: "Wang Xiaohu",
          course: "Digital",
          score: "75"} / /... Too long [Copy the code

Declare two key arrays in data:

// Merge cell colNameArray: ["class"."name",], // Array of columns to merge [field name 1, field name 2, field name 2...] MergeArray: [] // Calculates an array of merged rowsCopy the code

Edit the calculation function:

You can merge rows or columns by passing the SPAN-method method to the table. The parameter of the method is an object containing four attributes: row, column, rowIndex, and columnIndex. This function returns an array of two elements, the first representing RowSPAN and the second representing ColSPAN. You can also return an object with keys named RowSPAN and ColSPAN.

You want to edit a function span-method to calculate rowSPAN and colSPAN for each cell;

Before writing the span-method function, figure out which cells to merge and the rules for merging. In the table above, for the moment, it is the class and name rows that need to be merged; That is, cells of a class or the same name are displayed together. The effect is as follows:

So you first have a function that handles the merge rules and the rows and columns that you merge.

Write a common tool, mergecell.js: / SRC /util/ mergecell.js

letcolNumArray = []; // The number of rows to be merged for each columnletcolPosIndexArray = []; // Record the position of the column to be merged /** * data initialization * @param {number of columns to be merged, i.e. the length of the array of field names colnamearrayparam.length} colNum */function initMerge(colNum) {
    colNumArray = [], colPosIndexArray = [];
    for (leti = 0; i < colNum; i++) { colNumArray.push([1]); // Initialize the first line colposIndexArray.push ([0]); } /** * Merge process * @param {array of field names to merge} colNameArrayParam * @param {source data to merge} dataParam */ const colNumberMergeCount =function (colNameArrayParam, dataParam) {
    for (leti = 0; i < dataParam.length; I++) {// iterate over each piece of dataif(i == 0) { initMerge(colNameArrayParam.length); // initialize the first line}else {
            let isAnd = true; // The first and second columns must be merged before the current column is mergedfor (letj = 0; j < colNameArrayParam.length; J++) {// iterate over the columns to be merged and count the number of rows to be mergedif(isAnd && dataParam[I][colNameArrayParam[j]]] === dataParam[i-1][colNameArrayParam[j]]) {// Check whether the content is the same as that in the previous column colNumArray[j][colPosIndexArray[j]] += 1; ColNumArray [j]. Push (0); // Push a new line 0 to indicate that this line is merged isAnd =true; // Record and relationship}else {
                    isAnd = false; ColNumArray [j]. Push (1); // Push new row defaults to 1 colPosIndexArray[j] = I; }}}} console.log(colNumArray); // Update the position of the merged rows, for example, from the first line, if the position is always the same, then push the new action 0, otherwise, do not merge the newly updated position +1, from the next line to merge}}}} console.log(colNumArray).returncolNumArray; * @param {span-method callback parameter} param0 */functionspanMethod({ row, column, rowIndex, columnIndex }) { const _row = colNumArray[columnIndex][rowIndex]; const _col = _row > 0 ? 1:0; // If _row=0 is merged, its column needs to be cancelledreturn {
        rowspan: _row,
        colspan: _col
    };
}
export default colNumberMergeCount;
Copy the code

Introduced into a component:

import mergeCell from "@/util/mergeCell"; 
Copy the code

Define a function to process an array that accepts the raw data and the columns to be merged, and return the processed array (containing the merged cell information {rowspan,colsapn}) :

Merge (data) {this.mergeArray = mergeCell(this.colNameArray, data); },Copy the code

This. MergeArray is the array that we declared to receive and process the merge result. The array holds the merge rule for the cells.

Span-method:

ArraySpanMethod ({row, column, rowIndex, columnIndex}) {if(columnIndex < this.mergeArray.length) { const _row = this.mergeArray[columnIndex][rowIndex]; const _col = _row > 0 ? 1:0; // If _row=0 is merged, its column needs to be cancelledreturn{ rowspan: _row, colspan: _col }; }}Copy the code

Bind to

span-method property:

<el-table :data="tableData" stripe border :span-method="arraySpanMethod">
Copy the code

The last step calls the meger function:


created(){
  this.merge(this.tableData);
},

Copy the code

OK! To complete.

If you want to merge the previous two columns, you need to modify mergecell.js. You can extend one more function and seal it off into a generic library. All subsequent projects are available.

Git address