el-table same data row cell merge

background

The first column of the list in the project is the name, and the desired effect is to merge rows with the same name, as shown in the figure:Merge example

Implementation steps

1. Draw el-table

Draw a table according to the conventional writing method, and introduce the method of writing table merging rules according to the official document element-ui . span-method
in the code example

    <el-table v-loading="listLoading" :data="list" :span-method="objectSpanMethod" >
      <el-table-column prop="name" label="name" width="120"></el-table-column>
      <el-table-column prop="Title" label="Title" width="120"></el-table-column>
      <el-table-column prop="Pageviews" label="Pageviews" width="120" align="center"> </el-table-column>
      <el-table-column prop="Status" label="Status" width="110"> </el-table-column>
      <el-table-column prop="created_at" label="Display_time" width="200"></el-table-column>
    </el-table>

2. Write the merge method

2.1 Calculate the merged line number

  1. Define the global variable indexArray in data to store all merged row numbers;
  2. By passing in the row number and the name of the row, the number of rows with the same data below the row is calculated throughout
  methods: {
    
    
    getRows(rowIndex, name) {
    
    
      let count = 0
      for (let i = rowIndex; i < this.list.length; i++) {
    
    
        if (this.list[i].name === name) {
    
    
          count++
        } else {
    
    
          break
        }
      }
      return count
    }
  }

2.2 Calculate the indexArray of the merged line number array .

Calculate the merged line number array indexArray when the component mounted is built

  let count = 0
  for (let rowIndex = 0; rowIndex < this.list.length; ) {
    
    
    this.indexArray.push(rowIndex)
    count = this.getRows(rowIndex, this.list[rowIndex].name)
    rowIndex += count
  }

Among them, list is the data source of the entire table

2.3 Write the line number merging method

When the rowIndex of the row is in the merged row number array, return the merged row data, otherwise return empty.

  methods: {
    
    
    objectSpanMethod({
     
      row, column, rowIndex, columnIndex }) {
    
    
      if (columnIndex === 0) {
    
    
        let rowCount = 0
        if (this.indexArray.includes(rowIndex)) {
    
    
          rowCount = this.getRows(rowIndex, row.name)
          return {
    
    
            rowspan: rowCount,
            colspan: 1
          }
        } else {
    
    
          return {
    
    
            rowspan: 0,
            colspan: 0
          }
        }
      }
    }
  }

(Author Sui Sui Nian) The official website also uses the line number to control the merge. I always wanted to use the attribute value of the list to judge at the beginning, but I always fell into an infinite loop. This implementation method is not good. If the boss has more Comments are welcome for good implementation methods, and I am very grateful! ! !

3. All codes

The project code is not convenient to disclose, this is a complete implementation code I simplified:

<template>
  <div class="app-container">
    <el-table :data="list" :span-method="objectSpanMethod">
      <el-table-column prop="name" label="name" width="120" />
      <el-table-column prop="title" label="Title" width="120" />
      <el-table-column prop="pageviews" label="Pageviews" width="120" />
      <el-table-column prop="status" label="Status" width="110" />
      <el-table-column prop="display_time" label="Display_time" width="200" />
    </el-table>
  </div>
</template>

<script>
export default {
    
    
  data() {
    
    
    return {
    
    
      list: [
        {
    
    
          name: '张三',
          title: '文本一',
          status: 'published',
          display_time: '2023-07-14',
          pageviews: 200
        },
        {
    
    
          name: '李四',
          title: '文本二',
          status: 'published',
          display_time: '2023-07-14',
          pageviews: 200
        },
        {
    
    
          name: '李四',
          title: '文本三',
          status: 'published',
          display_time: '2023-07-14',
          pageviews: 200
        },
        {
    
    
          name: '王五',
          title: '文本四',
          status: 'published',
          display_time: '2023-07-14',
          pageviews: 200
        },
        {
    
    
          name: '王五',
          title: '文本五',
          status: 'published',
          display_time: '2023-07-14',
          pageviews: 200
        },
        {
    
    
          name: '王五',
          title: '文本六',
          status: 'published',
          display_time: '2023-07-14',
          pageviews: 200
        }
      ],
      indexArray: []
    }
  },
  mounted() {
    
    
    let count = 0
    for (let rowIndex = 0; rowIndex < this.list.length; ) {
    
    
      this.indexArray.push(rowIndex)
      count = this.getRows(rowIndex, this.list[rowIndex].name)
      rowIndex += count
    }
  },
  methods: {
    
    
    objectSpanMethod({
     
      row, column, rowIndex, columnIndex }) {
    
    
      if (columnIndex === 0) {
    
    
        let rowCount = 0
        if (this.indexArray.includes(rowIndex)) {
    
    
          rowCount = this.getRows(rowIndex, row.name)
          return {
    
    
            rowspan: rowCount,
            colspan: 1
          }
        } else {
    
    
          return {
    
    
            rowspan: 0,
            colspan: 0
          }
        }
      }
    },
    getRows(rowIndex, name) {
    
    
      let count = 0
      for (let i = rowIndex; i < this.list.length; i++) {
    
    
        if (this.list[i].name === name) {
    
    
          count++
        } else {
    
    
          break
        }
      }
      return count
    }
  }
}
</script>

Guess you like

Origin blog.csdn.net/problemRecord/article/details/131718956