el-table表格動態(tài)合并相同數(shù)據(jù)單元格(可指定列+自定義合并)
1.固定合并
- 官方挺提供的合并具體某行列的方法:el-table合并行或列
- 通過給table傳入span-method方法可以實現(xiàn)合并行或列,方法的參數(shù)是一個對象,里面包含當(dāng)前行row、當(dāng)前列column、當(dāng)前行號rowIndex、當(dāng)前列號columnIndex四個屬性。
該函數(shù)可以返回一個包含兩個元素的數(shù)組,第一個元素代表rowspan,第二個元素代表colspan。 也可以返回一個鍵名為rowspan和colspan的對象。
<template>
<div>
<el-table
:data="tableData"
:span-method="arraySpanMethod"
border
style="width: 100%">
<el-table-column
prop="id"
label="ID"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="姓名">
</el-table-column>
<el-table-column
prop="amount1"
sortable
label="數(shù)值 1">
</el-table-column>
<el-table-column
prop="amount2"
sortable
label="數(shù)值 2">
</el-table-column>
<el-table-column
prop="amount3"
sortable
label="數(shù)值 3">
</el-table-column>
</el-table>
<el-table
:data="tableData"
:span-method="objectSpanMethod"
border
style="width: 100%; margin-top: 20px">
<el-table-column
prop="id"
label="ID"
width="180">
</el-table-column>
<el-table-column
prop="name"
label="姓名">
</el-table-column>
<el-table-column
prop="amount1"
label="數(shù)值 1(元)">
</el-table-column>
<el-table-column
prop="amount2"
label="數(shù)值 2(元)">
</el-table-column>
<el-table-column
prop="amount3"
label="數(shù)值 3(元)">
</el-table-column>
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
tableData: [{
id: '12987122',
name: '王小虎',
amount1: '234',
amount2: '3.2',
amount3: 10
}, {
id: '12987123',
name: '王小虎',
amount1: '165',
amount2: '4.43',
amount3: 12
}, {
id: '12987124',
name: '王小虎',
amount1: '324',
amount2: '1.9',
amount3: 9
}, {
id: '12987125',
name: '王小虎',
amount1: '621',
amount2: '2.2',
amount3: 17
}, {
id: '12987126',
name: '王小虎',
amount1: '539',
amount2: '4.1',
amount3: 15
}]
};
},
methods: {
arraySpanMethod({ row, column, rowIndex, columnIndex }) {
if (rowIndex % 2 === 0) {
if (columnIndex === 0) {
return [1, 2];
} else if (columnIndex === 1) {
return [0, 0];
}
}
},
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
if (columnIndex === 0) {
if (rowIndex % 2 === 0) {
return {
rowspan: 2,
colspan: 1
};
} else {
return {
rowspan: 0,
colspan: 0
};
}
}
}
}
};
</script>運(yùn)行效果:


缺點(diǎn):這種只適合寫死的數(shù)據(jù)和固定的表格行列,無法動態(tài)判斷單元格數(shù)據(jù)是否相等再合并;
2. 動態(tài)合并相同數(shù)據(jù)單元格(所有列)
- 可以對所有相同數(shù)據(jù)的列,進(jìn)行動態(tài)合并
- 此方法適合需要合并所有的相同數(shù)據(jù)的單元格
<template>
<div>
<el-table
:data="tableData"
:span-method="objectSpanMethod"
border
:header-cell-style="{ textAlign: 'center', backgroundColor: '#F5F7FA' }"
>
<el-table-column prop="School" label="學(xué)校" align="center">
</el-table-column>
<el-table-column prop="Grade" label="年級" align="center" />
<el-table-column prop="Class" label="班級" align="center" />
<el-table-column prop="Name" label="姓名" align="center" />
<el-table-column prop="Chinese" label="語文" align="center" />
<el-table-column prop="Math" label="數(shù)學(xué)" align="center" />
<el-table-column prop="English" label="英語" align="center" />
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
// 存放所有的表頭 一定要與tableData一致
colFields: [
"School",
"Grade",
"Class",
"Name",
"Chinese",
"Math",
"English",
],
spanArr: [], //存儲合并單元格的開始位置
// 表格數(shù)據(jù)
tableData: [
// 一年級
{
School: "第一小學(xué)",
Grade: "1年級",
Class: "1班",
Name: "張三",
Chinese: "90",
Math: "100",
English: "80",
},
{
School: "第一小學(xué)",
Grade: "1年級",
Class: "2班",
Name: "李四",
Chinese: "90",
Math: "85",
English: "80",
},
{
School: "第一小學(xué)",
Grade: "1年級",
Class: "3班",
Name: "王五",
Chinese: "79",
Math: "100",
English: "80",
},
// 二年級
{
School: "第一小學(xué)",
Grade: "2年級",
Class: "1班",
Name: "趙六",
Chinese: "95",
Math: "100",
English: "80",
},
{
School: "第一小學(xué)",
Grade: "2年級",
Class: "2班",
Name: "錢八",
Chinese: "98",
Math: "85",
English: "80",
},
{
School: "第一小學(xué)",
Grade: "2年級",
Class: "3班",
Name: "陳九",
Chinese: "79",
Math: "100",
English: "80",
},
// 三年級
{
School: "第一小學(xué)",
Grade: "3年級",
Class: "1班",
Name: "黃十",
Chinese: "91",
Math: "88",
English: "80",
},
{
School: "第一小學(xué)",
Grade: "3年級",
Class: "2班",
Name: "魏一",
Chinese: "90",
Math: "86",
English: "87",
},
{
School: "第一小學(xué)",
Grade: "3年級",
Class: "3班",
Name: "楊二",
Chinese: "79",
Math: "99",
English: "80",
},
],
};
},
methods: {
/**
* 分析每一列,找出相同的
* @param data
*/
getSpanArr() {
for (let i = 0; i < this.tableData.length; i++) {
let row = i;
// let col = i % this.colCount;
if (row === 0) {
// i 表示行 j表示列
for (let j = 0; j < this.colFields.length; j++) {
this.spanArr[i * this.colFields.length + j] = {
rowspan: 1,
colspan: 1,
};
}
} else {
for (let j = 0; j < this.colFields.length; j++) {
// 當(dāng)前和上一次的一樣
// 1. 合并所有列的相同數(shù)據(jù)單元格
if (
this.tableData[row][this.colFields[j]] ===
this.tableData[row - 1][this.colFields[j]]
) {
let beforeItem =
this.spanArr[(row - 1) * this.colFields.length + j];
this.spanArr[row * this.colFields.length + j] = {
rowspan: 1 + beforeItem.rowspan, // 合并幾行
colspan: 1, // 合并幾列,我這里只是跨行合并,不跨列合并,所以用的1
};
beforeItem.rowspan = 0;
beforeItem.colspan = 0;
} else {
// rowspan 和 colspan 都為1表格此單元格不合并
this.spanArr[row * this.colFields.length + j] = {
rowspan: 1,
colspan: 1,
};
}
}
}
}
// 對數(shù)據(jù)進(jìn)行倒序
let stack = [];
for (let i = 0; i < this.colFields.length; i++) {
for (let j = 0; j < this.tableData.length; j++) {
// console.log("i=" + i + " j=" + j);
// i 表示列 j表示行
if (j === 0) {
if (this.spanArr[j * this.colFields.length + i].rowspan === 0) {
stack.push(this.spanArr[j * this.colFields.length + i]);
}
} else {
if (this.spanArr[j * this.colFields.length + i].rowspan === 0) {
stack.push(this.spanArr[j * this.colFields.length + i]);
} else {
stack.push(this.spanArr[j * this.colFields.length + i]);
while (stack.length > 0) {
let pop = stack.pop();
let len = stack.length;
this.spanArr[(j - len) * this.colFields.length + i] = pop;
}
}
}
}
}
// console.log(this.spanArr);
},
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
// console.log(this.spanArr[rowIndex * this.colFields.length + columnIndex]);
return this.spanArr[rowIndex * this.colFields.length + columnIndex];
},
},
mounted() {
this.getSpanArr();
},
};
</script>
<style lang="scss" scoped></style>效果:

我們可以看到,所有列,只要數(shù)據(jù)相同的單元格都被合并了,包括我不想合并的單元格,這時候就要指定合并的列了

3. 動態(tài)合并相同數(shù)據(jù)單元格(指定列)
只需要加個if判斷即可指定要合并哪些列
// 這里只放了部分代碼,除了加了個if,其他代碼和上面的一樣
getSpanArr() {
for (let i = 0; i < this.tableData.length; i++) {
let row = i;
// let col = i % this.colCount;
if (row === 0) {
// i 表示行 j表示列
for (let j = 0; j < this.colFields.length; j++) {
this.spanArr[i * this.colFields.length + j] = {
rowspan: 1,
colspan: 1,
};
}
} else {
for (let j = 0; j < this.colFields.length; j++) {
// 當(dāng)前和上一次的一樣
// 合并所有列的相同數(shù)據(jù)單元格
if (
this.colFields[j] == "School" ||
this.colFields[j] == "Grade" ||
this.colFields[j] == "Class"
) { // 指定合并哪些列
if (
this.tableData[row][this.colFields[j]] ===
this.tableData[row - 1][this.colFields[j]]
) {
let beforeItem =
this.spanArr[(row - 1) * this.colFields.length + j];
this.spanArr[row * this.colFields.length + j] = {
rowspan: 1 + beforeItem.rowspan,
colspan: 1,
};
beforeItem.rowspan = 0;
beforeItem.colspan = 0;
} else {
// rowspan 和 colspan 都為1表格此單元格不合并
this.spanArr[row * this.colFields.length + j] = {
rowspan: 1,
colspan: 1,
};
}
}
}
}
}效果:這樣就只合并了我們指定的那幾列了

4. 動態(tài)合并相同數(shù)據(jù)單元格(指定列+合并條件)
有時候我們會遇到不想合并的單元格,比如下面這種情況:

按常理來說,不同小學(xué)的數(shù)據(jù)應(yīng)該是不做合并才對,正確是這種:

這時候就需要加上一些自定義的合并條件了:
getSpanArr() {
for (let i = 0; i < this.tableData.length; i++) {
let row = i;
// let col = i % this.colCount;
if (row === 0) {
// i 表示行 j表示列
for (let j = 0; j < this.colFields.length; j++) {
this.spanArr[i * this.colFields.length + j] = {
rowspan: 1,
colspan: 1,
};
}
} else {
for (let j = 0; j < this.colFields.length; j++) {
// 當(dāng)前和上一次的一樣
// 合并所有列的相同數(shù)據(jù)單元格
if (
this.colFields[j] == "School" ||
this.colFields[j] == "Grade" ||
this.colFields[j] == "Class"
) { // 指定合并哪些列
if (
this.tableData[row]["School"] !==
this.tableData[row - 1]["School"]
) { // 哪些不合并:School不一樣的,不合并
this.spanArr[row * this.colFields.length + j] = {
rowspan: 1,
colspan: 1,
};
} else if (
this.tableData[row][this.colFields[j]] ===
this.tableData[row - 1][this.colFields[j]]
) {
let beforeItem =
this.spanArr[(row - 1) * this.colFields.length + j];
this.spanArr[row * this.colFields.length + j] = {
rowspan: 1 + beforeItem.rowspan,// 合并幾列
colspan: 1,// 合并幾行
};
beforeItem.rowspan = 0;
beforeItem.colspan = 0;
} else {
// rowspan 和 colspan 都為1表格此單元格不合并
this.spanArr[row * this.colFields.length + j] = {
rowspan: 1,
colspan: 1,
};
}
}
}
}
}
// console.log(this.spanArr);
},這時候再看,就是我們想要的效果了

完整代碼
最后附完整代碼:
<template>
<div>
<el-table
:data="tableData"
:span-method="objectSpanMethod"
border
:header-cell-style="{ textAlign: 'center', backgroundColor: '#F5F7FA' }"
>
<el-table-column prop="School" label="學(xué)校" align="center">
</el-table-column>
<el-table-column prop="Grade" label="年級" align="center" />
<el-table-column prop="Class" label="班級" align="center" />
<el-table-column prop="Name" label="姓名" align="center" />
<el-table-column prop="Chinese" label="語文" align="center" />
<el-table-column prop="Math" label="數(shù)學(xué)" align="center" />
<el-table-column prop="English" label="英語" align="center" />
</el-table>
</div>
</template>
<script>
export default {
data() {
return {
// 存放所有的表頭 一定要與tableData一致
colFields: [
"School",
"Grade",
"Class",
"Name",
"Chinese",
"Math",
"English",
],
spanArr: [], //存儲合并單元格的開始位置
// 表格數(shù)據(jù)
tableData: [
// 一年級
{
School: "第一小學(xué)",
Grade: "1年級",
Class: "1班",
Name: "張三",
Chinese: "90",
Math: "100",
English: "80",
},
{
School: "第一小學(xué)",
Grade: "1年級",
Class: "1班",
Name: "張偉",
Chinese: "90",
Math: "99",
English: "89",
},
{
School: "第一小學(xué)",
Grade: "1年級",
Class: "2班",
Name: "李四",
Chinese: "90",
Math: "85",
English: "80",
},
{
School: "第一小學(xué)",
Grade: "1年級",
Class: "3班",
Name: "王五",
Chinese: "79",
Math: "100",
English: "80",
},
// 二年級
{
School: "第一小學(xué)",
Grade: "2年級",
Class: "1班",
Name: "趙六",
Chinese: "95",
Math: "100",
English: "80",
},
{
School: "第一小學(xué)",
Grade: "2年級",
Class: "2班",
Name: "錢八",
Chinese: "98",
Math: "85",
English: "80",
},
{
School: "第一小學(xué)",
Grade: "2年級",
Class: "3班",
Name: "陳九",
Chinese: "79",
Math: "100",
English: "100",
},
// 三年級
{
School: "第一小學(xué)",
Grade: "3年級",
Class: "1班",
Name: "黃十",
Chinese: "91",
Math: "88",
English: "80",
},
{
School: "第一小學(xué)",
Grade: "3年級",
Class: "2班",
Name: "魏一",
Chinese: "90",
Math: "86",
English: "87",
},
{
School: "第一小學(xué)",
Grade: "3年級",
Class: "3班",
Name: "楊二",
Chinese: "79",
Math: "99",
English: "80",
},
// 第二小學(xué)
{
School: "第二小學(xué)",
Grade: "3年級",
Class: "3班",
Name: "袁零",
Chinese: "79",
Math: "99",
English: "80",
},
],
};
},
methods: {
/**
* 分析每一列,找出相同的
* @param data
*/
getSpanArr() {
for (let i = 0; i < this.tableData.length; i++) {
let row = i;
// let col = i % this.colCount;
if (row === 0) {
// i 表示行 j表示列
for (let j = 0; j < this.colFields.length; j++) {
this.spanArr[i * this.colFields.length + j] = {
rowspan: 1,
colspan: 1,
};
}
} else {
for (let j = 0; j < this.colFields.length; j++) {
// 當(dāng)前和上一次的一樣
// 合并所有列的相同數(shù)據(jù)單元格
if (
this.colFields[j] == "School" ||
this.colFields[j] == "Grade" ||
this.colFields[j] == "Class"
) { // 指定合并哪些列
if (
this.tableData[row]["School"] !==
this.tableData[row - 1]["School"]
) { // 哪些不合并:School不一樣的,不合并
this.spanArr[row * this.colFields.length + j] = {
rowspan: 1,
colspan: 1,
};
} else if (
this.tableData[row][this.colFields[j]] ===
this.tableData[row - 1][this.colFields[j]]
) {
let beforeItem =
this.spanArr[(row - 1) * this.colFields.length + j];
this.spanArr[row * this.colFields.length + j] = {
rowspan: 1 + beforeItem.rowspan,// 合并幾列
colspan: 1,// 合并幾行
};
beforeItem.rowspan = 0;
beforeItem.colspan = 0;
} else {
// rowspan 和 colspan 都為1表格此單元格不合并
this.spanArr[row * this.colFields.length + j] = {
rowspan: 1,
colspan: 1,
};
}
}
}
}
}
// 對數(shù)據(jù)進(jìn)行倒序
let stack = [];
for (let i = 0; i < this.colFields.length; i++) {
for (let j = 0; j < this.tableData.length; j++) {
// console.log("i=" + i + " j=" + j);
// i 表示列 j表示行
if (j === 0) {
if (this.spanArr[j * this.colFields.length + i].rowspan === 0) {
stack.push(this.spanArr[j * this.colFields.length + i]);
}
} else {
if (this.spanArr[j * this.colFields.length + i].rowspan === 0) {
stack.push(this.spanArr[j * this.colFields.length + i]);
} else {
stack.push(this.spanArr[j * this.colFields.length + i]);
while (stack.length > 0) {
let pop = stack.pop();
let len = stack.length;
this.spanArr[(j - len) * this.colFields.length + i] = pop;
}
}
}
}
}
// console.log(this.spanArr);
},
objectSpanMethod({ row, column, rowIndex, columnIndex }) {
// console.log(this.spanArr[rowIndex * this.colFields.length + columnIndex]);
return this.spanArr[rowIndex * this.colFields.length + columnIndex];
},
},
mounted() {
this.getSpanArr();
},
};
</script>
<style lang="scss" scoped></style>參考:https://blog.csdn.net/u010735120/article/details/122184493
到此這篇關(guān)于el-table表格動態(tài)合并相同數(shù)據(jù)單元格(可指定列+自定義合并)的文章就介紹到這了,更多相關(guān)el-table 動態(tài)合并單元格內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue+jquery+lodash實現(xiàn)滑動時頂部懸浮固定效果
這篇文章主要為大家詳細(xì)介紹了vue+jquery+lodash實現(xiàn)滑動時頂部懸浮固定效果,具有一定的參考價值,感興趣的小伙伴們可以參考一下2018-04-04
vue3路由跳轉(zhuǎn)params傳參接收不到的解決辦法
這篇文章主要給大家介紹了關(guān)于vue3路由跳轉(zhuǎn)params傳參接收不到的解決辦法,Vue3是目前前端開發(fā)中非常流行的框架之一,文中通過實例代碼介紹的非常詳細(xì),需要的朋友可以參考下2023-06-06
vue的異步數(shù)據(jù)更新機(jī)制與$nextTick用法解讀
這篇文章主要介紹了vue的異步數(shù)據(jù)更新機(jī)制與$nextTick用法解讀,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2023-03-03

