Merge the same content in el-table list
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:
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
- Define the global variable indexArray in data to store all merged row numbers;
- 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>