[TOC]
>[success] # Element UI table合并行(上下行)
通過給`table`傳入`span-method`方法可以實現合并行或列,方法的參數是一個對象,里面包含當前行`row`、當前列`column`、當前行號`rowIndex`、當前列號`columnIndex`四個屬性。該函數可以返回一個包含兩個元素的數組,第一個元素代表`rowspan`,第二個元素代表`colspan`。 也可以返回一個鍵名為`rowspan`和`colspan`的對象。
>[success] ## 官方案例
如圖,上面的表格時合并列,下面的表格是合并行

html
~~~
<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 prop="name" label="姓名"/>
<el-table-column prop="amount1" sortable label="數值 1"/>
<el-table-column prop="amount2" sortable label="數值 2"/>
<el-table-column prop="amount3" sortable label="數值 3"/>
</el-table>
<br>
<br>
<br>
<br>
<!-- 合并行 -->
<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 prop="name" label="姓名"/>
<el-table-column prop="amount1" label="數值 1(元)"/>
<el-table-column prop="amount2" label="數值 2(元)"/>
<el-table-column prop="amount3" label="數值 3(元)"/>
</el-table>
</div>
</template>
~~~
Javascript
~~~
<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) { // 列索引為 第1列時
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, // 要合并的行數,為 0 則直接不顯示
colspan: 0 // 要合并的列數,為 0 則直接不顯示
};
}
}
}
}
}
</script>
~~~
<br/>
>[success] ## 每列按照同一種規則合并行(上下行)
假如我想寫下面這樣的表格,第1、2、3和最后一列的合并方式都一樣。

html
~~~
<template>
<div>
<el-table :data="tableData" border :span-method="objectSpanMethod">
<el-table-column type="selection" align="center" width="55" />
<el-table-column prop="taxerName" label="企業名稱" align="center" />
<el-table-column prop="taxerId" label="稅號" align="center" />
<el-table-column prop="terminalId" label="盤編號" align="center" />
<el-table-column prop="invoiceType" label="發票類型" align="center" width="100px"/>
<el-table-column prop="status" label="抄報狀態" align="center" width="100px" />
<el-table-column prop="taxReturnResult" label="抄報結果" align="center" />
<el-table-column prop="unlockResult" label="反寫結果" align="center" />
<el-table-column prop="invoiceEndDate" label="開票截止日期" align="center" />
<el-table-column prop="taxReturnDate" label="最新報稅日期" align="center" />
<el-table-column fixed="right" label="操作" align="center">
<template slot-scope="scope">
<el-button type="text" size="small">查看詳情</el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
~~~
Javascript
~~~
<script>
export default{
data() {
return {
tableData: [
{
"deviceId": "463346577777888888888",
"taxerName": "123",
"taxerId": "4762455555555543333333",
"terminalId": "346537568756876888888",
"invoiceTypes": ["025", "026", "004", "007"],
"rowspan": 1 // rowspan 1:表示不合并
},
{
"deviceId": "645767777754675677777",
"taxerName": "234",
"taxerId": "234444442342344444",
"terminalId": "432524355555333333",
"invoiceTypes": ["004", "007", "025", "026"],
"invoiceType": "004",
"status": 3,
"taxReturnResult": "成功",
"unlockResult": "失敗",
"invoiceEndDate": "2019-04-15",
"taxReturnDate": "2019-03-31",
"rowspan": 4 // rowspan 4:表示合并下方的三行,共合并四行
},
{
"deviceId": "645767777754675677777",
"taxerName": "234",
"taxerId": "234444442342344444",
"terminalId": "432524355555333333",
"invoiceTypes": ["004", "007", "025", "026"],
"invoiceType": "026",
"status": 3,
"taxReturnResult": "成功",
"unlockResult": "失敗",
"invoiceEndDate": "2019-04-15",
"taxReturnDate": "2019-03-31",
"rowspan": 0 // rowspan 0:表示已被上面的行合并,該單元格不顯示
},
{
"deviceId": "645767777754675677777",
"taxerName": "234",
"taxerId": "234444442342344444",
"terminalId": "432524355555333333",
"invoiceTypes": ["004", "007", "025", "026"],
"invoiceType": "007",
"status": 3,
"taxReturnResult": "成功",
"unlockResult": "失敗",
"invoiceEndDate": "2019-04-15",
"taxReturnDate": "2019-03-31",
"rowspan": 0 // rowspan 0:表示已被上面的行合并,該單元格不顯示
},
{
"deviceId": "645767777754675677777",
"taxerName": "234",
"taxerId": "234444442342344444",
"terminalId": "432524355555333333",
"invoiceTypes": ["004", "007", "025", "026"],
"invoiceType": "025",
"status": 3,
"taxReturnResult": "成功",
"unlockResult": "失敗",
"invoiceEndDate": "2019-04-15",
"taxReturnDate": "2019-03-31",
"rowspan": 0 // rowspan 0:表示已被上面的行合并,該單元格不顯示
},
{
"deviceId": "756465866856767677777",
"taxerName": "555",
"taxerId": "453623465234645555455",
"terminalId": "6436543565455555",
"invoiceTypes": ["004", "007", "025", "026"],
"invoiceType": "007",
"status": 3,
"taxReturnResult": null,
"unlockResult": null,
"invoiceEndDate": "2019-04-15",
"taxReturnDate": "2019-03-31",
"rowspan": 3 // rowspan 3:表示合并下方的2行,共合并3行
},
{
"deviceId": "756465866856767677777",
"taxerName": "555",
"taxerId": "453623465234645555455",
"terminalId": "6436543565455555",
"invoiceTypes": ["004", "007", "025", "026"],
"invoiceType": "026",
"status": 3,
"taxReturnResult": null,
"unlockResult": null,
"invoiceEndDate": "2019-04-15",
"taxReturnDate": "2019-03-31",
"rowspan": 0 // rowspan 0:表示已被上面的行合并,該單元格不顯示
},
{
"deviceId": "756465866856767677777",
"taxerName": "555",
"taxerId": "453623465234645555455",
"terminalId": "6436543565455555",
"invoiceTypes": ["004", "007", "025", "026"],
"invoiceType": "004",
"status": 3,
"taxReturnResult": null,
"unlockResult": null,
"invoiceEndDate": "2019-04-15",
"taxReturnDate": "2019-03-31",
"rowspan": 0 // rowspan 0:表示已被上面的行合并,該單元格不顯示
},
{
"deviceId": "46365546555555555",
"taxerName": "666",
"taxerId": "787654545314312",
"terminalId": "789765454151453",
"invoiceTypes": ["004", "026"],
"invoiceType": "026",
"status": 3,
"taxReturnResult": "成功",
"unlockResult": "失敗",
"invoiceEndDate": "2019-04-18",
"taxReturnDate": "2019-03-31",
"rowspan": 2// rowspan 2:表示合并下方的1行,共合并2行
},
{
"deviceId": "46365546555555555",
"taxerName": "666",
"taxerId": "787654545314312",
"terminalId": "789765454151453",
"invoiceTypes": ["004", "026"],
"invoiceType": "004",
"status": 3,
"taxReturnResult": "成功",
"unlockResult": "失敗",
"invoiceEndDate": "2019-04-18",
"taxReturnDate": "2019-03-31",
"rowspan": 0 // rowspan 0:表示已被上面的行合并,該單元格不顯示
}
]
}
},
methods: {
objectSpanMethod ({ row, column, rowIndex, columnIndex }) {
// 之前我這么些判斷,有點小蠢...
// if (columnIndex === 0 || columnIndex === 1 || columnIndex === 2 || columnIndex === 3 || columnIndex === 10) {
// 要合并的列的索引
let arr = [0, 1, 2, 3, 10]
// 設置要合并的列
if (arr.indexOf(columnIndex) !== -1) {
// 用于設置合并開始的行號,rowspan 不為 0,不是第一行時, 則該行需要向下合并
if (column.rowSpan !== 0) {
return {
rowspan: row.rowspan, // 要合并的行數
colspan: 1
}
} else {
return {
rowspan: 0, // column.rowspan === 0 隱藏該單元格
colspan: 0
}
}
}
}
}
}
</script>
~~~
<br/>
>[success] ## 每列都有自己的合并方式(合并行)
如圖我想寫一個這種表格,第一列和第二列的合并行數都不同。

html
~~~
<template>
<div>
<el-table :data="permissionData" border :span-method="objectSpanMethod">
<el-table-column prop="deviceId" label="企業名稱" align="center" />
<el-table-column prop="taxerName" label="稅號" align="center" />
<el-table-column prop="taxerId" label="盤編號" align="center" />
</el-table>
</div>
</template>
~~~
Javascript
~~~
<script>
export default{
data() {
return {
permissionData: [
{
'deviceId': '首頁',
'taxerName': '',
'taxerId': '',
'rowspan': [1, 1]
},
{
'deviceId': '管理功能',
'taxerName': '預開審核',
'taxerId': '預開審核管理',
'rowspan': [6, 1]
},
{
'deviceId': '管理功能',
'taxerName': '發票查詢',
'taxerId': '已開發票查詢',
'rowspan': [0, 3]
},
{
'deviceId': '管理功能',
'taxerName': '發票查詢',
'taxerId': '未上傳發票查詢',
'rowspan': [0, 0]
},
{
'deviceId': '管理功能',
'taxerName': '發票查詢',
'taxerId': '驗簽失敗發票查詢',
'rowspan': [0, 0]
},
{
'deviceId': '管理功能',
'taxerName': '商戶綜合管理',
'taxerId': '稅控設備列表',
'rowspan': [0, 2]
},
{
'deviceId': '管理功能',
'taxerName': '商戶綜合管理',
'taxerId': '數據抄報',
'rowspan': [0, 0]
}
]
}
},
methods: {
// 合并表格
objectSpanMethod ({ row, column, rowIndex, columnIndex }) {
let arr = [0, 1]
// 設置要合并的列
if (arr.indexOf(columnIndex) !== -1) {
if (column.rowSpan !== 0) {
// 第一列
if (columnIndex === 0) {
return {
rowspan: row.rowspan[0],
colspan: 1
}
}
// 第二列
else if(columnIndex === 1){
return {
rowspan: row.rowspan[1],
colspan: 1
}
}
} else {
return {
rowspan: 0,
colspan: 0
}
}
}
}
}
}
</script>
~~~
<br/>
>[success] ## 須知
~~~
以上幾種'表格合并',不管是'每列按照同一種方式來合并',還是'每列都有自己的合并方式',他們都有一個
共同點,'同一種方式合并行'需要在數據中返回一個'數值','每列都有自己的合并方式'需要返回一個數組,
并且需要在 'objectSpanMethod'方法中'判斷是第幾列',每列使用的'rowspan'都不同,上面寫的都是
'靜態數據',那數據是后臺給的動態數據,rowspan又該如何計算,如何把數據整合成想要的格式呢?
~~~
<br/>
>[success] ## 合并表格案例(cv工程師直接來這里)
~~~
下面的例子中如果'想多列合并',而且'根據數據動態合并',就需要手動寫一個'this.getSpanArr()'方法,
然后在data中再定義一個'記錄行合并數的數組'
~~~

html
~~~
<template>
<div>
<el-table :data="permissionData" border :span-method="cellMerge">
<el-table-column prop="deviceId" label="企業名稱" align="center" />
<el-table-column prop="taxerName" label="稅號" align="center" />
<el-table-column prop="taxerId" label="盤編號" align="center" />
</el-table>
</div>
</template>
~~~
Javascript
~~~
<script>
export default{
data() {
return {
permissionData: [ // 接口數據
{
'deviceId': '首頁',
'taxerName': '',
'taxerId': ''
},
{
'deviceId': '管理功能',
'taxerName': '預開審核',
'taxerId': '預開審核管理'
},
{
'deviceId': '管理功能',
'taxerName': '發票查詢',
'taxerId': '已開發票查詢'
},
{
'deviceId': '管理功能',
'taxerName': '發票查詢',
'taxerId': '未上傳發票查詢',
},
{
'deviceId': '管理功能',
'taxerName': '發票查詢',
'taxerId': '驗簽失敗發票查詢'
},
{
'deviceId': '管理功能',
'taxerName': '商戶綜合管理',
'taxerId': '稅控設備列表'
},
{
'deviceId': '管理功能',
'taxerName': '商戶綜合管理',
'taxerId': '數據抄報'
}
],
spanArr: [], // deviceId的合并數
spanArr2: [] // taxerName的合并數
}
},
created(){
this.getSpanArr(this.permissionData,this.spanArr, 'deviceId')
this.getSpanArr(this.permissionData,this.spanArr2, 'taxerName')
},
methods: {
/**
* 記錄行合并數方法
* @param {array} data - 后臺拿到的數據
* @param {array} arr - 存放每一行記錄的合并數
* @param {string} property - 過濾屬性是否重復,參數為要過濾的屬性
*/
getSpanArr(data, arr, property) {
let pos = 0
for (var i = 0; i < data.length; i++) {
????if (i === 0) {
????????arr.push(1)
????????pos = 0
????} else {
????// 判斷當前元素與上一個元素是否相同
if (data[i][property] === data[i - 1][property]) {
????????arr[pos] += 1
????????arr.push(0)
????????} else {
????????arr.push(1)
pos = i
????????}
????}
}
},
// 合并行或列方法
cellMerge({ row, column, rowIndex, columnIndex }) {
???? if (columnIndex === 0) {
????????const _row = this.spanArr[rowIndex];
???????? const _col = _row > 0 ? 1 : 0
????????return {
????????????rowspan: _row,
???????????? colspan: _col
????????}
????}
else if(columnIndex === 1){
????????const _row = this.spanArr2[rowIndex]
???????? const _col = _row > 0 ? 1 : 0
????????return {
????????????rowspan: _row,
???????????? colspan: _col
????????}
}
}
}
}
</script>
~~~
>[success] ## 簡化合并行方法
上面的 **合并行方法** 如果有 **多列需要合并行** ,就要寫多個 **this.getSpanArr** 方法,多個 **spanArr** 數組,非常麻煩,可以使用下面這種方法來實現 **合并行**
**tableDemo.vue**
~~~
<template>
<div>
<el-table :data="dataSource" height="846" ref="tableList" border :header-cell-style="{ background: '#f5f7fa' }" :span-method="cellMerges">
<el-table-column label="二級指標" width="200" prop="twoLevel" show-overflow-tooltip align="center" />
<el-table-column label="三級指標" width="240" prop="threeLevel" show-overflow-tooltip align="center" />
<el-table-column label="評分項目" width="240" prop="evaluateProject" show-overflow-tooltip align="center" />
<el-table-column label="評分標準" align="left">
<template slot-scope="scope">
<div style="text-indent: 14px">{{ scope.row.evaluateStandard || '' }}</div>
</template>
</el-table-column>
<el-table-column label="分值" width="90" prop="score" show-overflow-tooltip align="center" />
<el-table-column label="土建" width="90" prop="structureScore" show-overflow-tooltip align="center">
<template slot-scope="scope">
<span>{{ scope.row.structureScore || scope.row.structureScore === 0 ? scope.row.structureScore : '-' }}</span>
</template>
</el-table-column>
<el-table-column label="機電" width="90" show-overflow-tooltip align="center">
<template slot-scope="scope">
<span>{{ scope.row.electroScore || scope.row.electroScore === 0 ? scope.row.electroScore : '-' }}</span>
</template>
</el-table-column>
<el-table-column label="均分" width="90" show-overflow-tooltip align="center">
<template slot-scope="scope">
<span>{{ scope.row.averageScore || scope.row.averageScore === 0 ? scope.row.averageScore : '-' }}</span>
</template>
</el-table-column>
<el-table-column label="操作" width="150" show-overflow-tooltip align="center">
<template slot-scope="scope">
<el-button type="text" size="small" @click.native.prevent="goGrade(scope.$index, dataSource)"> 評分 </el-button>
<el-button type="text" size="small" @click.native.prevent="goDeduction(scope.$index, dataSource)"> 扣分詳情 </el-button>
</template>
</el-table-column>
</el-table>
</div>
</template>
<script>
import Vue from 'vue'
import { Table, TableColumn ,Button } from 'element-ui'
import { mergeRows } from '../js/utils'
// 按需引入
Vue.use(Table)
Vue.use(Button)
Vue.use(TableColumn)
export default {
data() {
return {
dataSource: [
{
twoLevel: '能力指標 27',
threeLevel: '制度建設與落實 15',
evaluateProject: '1.1 責任劃分',
secondCode: '27',
thirdCode: '15',
itemCode: '1.1',
standardCode: '1.1.1',
evaluateStandard: '落實了全省隧道責任主體和監管主體,管理職責劃分明確,得40分;落實了責任主體和監管主體,但管理職責劃分不明確,得20分;落實了責任主體,但管理職責不明確,得10分;責任主體和監管主體不明晰,得0分',
score: 40,
structureScore: '40',
},
{
twoLevel: '能力指標 27',
threeLevel: '制度建設與落實 15',
evaluateProject: '1.2 監管能力',
evaluateStandard: '針對隧道養護管理工作有相關制度或指導性意見,較好,得40分;有相關制度或指導性意見,基本完善,得30分;有相關制度或指導性意見,但不完善,得10分;無相關制度或指導性意見,得0分',
score: 40,
secondCode: '27',
thirdCode: '15',
itemCode: '1.2',
standardCode: '1.2.1',
structureScore: '40',
}
]
}
},
methods: {
cellMerges({ rowIndex, columnIndex}) {
const mergeCfg = [
{ searchKey: 'secondCode', columnIndex: 0 },
{ searchKey: 'thirdCode', columnIndex: 1 },
{ searchKey: 'itemCode', columnIndex: 2 }
]
return mergeRows(rowIndex, columnIndex, this.dataSource, mergeCfg)
}
}
}
</script>
~~~
**合并行方法**
~~~
/**
* 合并行方法
* @param {*} rowIndex 行索引
* @param {*} columnIndex 列索引
* @param {*} dataSource 數據源
* @param {*} mergeCfg 合并配置 例如:[{searchKey: 'score', columnIndex: 0 }] searchKey:需檢索的屬性,columnIndex:代表要合并的列數
*/
export function mergeRows(rowIndex, columnIndex, dataSource, mergeCfg) {
for (let item of mergeCfg) {
let searchKey = item.searchKey
if (columnIndex === item.columnIndex) { // 要合并的列
if (rowIndex !== 0 && dataSource[rowIndex][searchKey] === dataSource[rowIndex - 1][searchKey]) { // 非第一行合并規則(非第一行,并且上一行跟當前行值相等,如果不相等就走else)
return [0, 0]
} else { // 第一行合并規則
let rowIndexCount = rowIndex
let count = 0
while (rowIndexCount + 1 < dataSource.length) { // 用當前行數據跟后續行數數據對比
if (dataSource[rowIndexCount + 1][searchKey] === dataSource[rowIndexCount][searchKey]) {
rowIndexCount++
count++
} else { // 數據不相等跳出循環
break
}
}
return [count + 1, 1]
}
}
}
}
~~~
- vue復選框邏輯
- get請求給后臺傳數組
- 提交表單時傳值參數處理方案
- Element ui上傳圖片功能
- async和await的使用
- 時間戳轉換
- 日期格式轉換時間戳
- 時間戳轉換日期格式
- 對深拷貝的認知總結
- vue-右鍵菜單功能
- textarea中換行、回車、空格的識別與處理
- element ui表格合并
- 合并行(上下行)
- 雙層for循環
- 數組去重
- 瀑布流
- 前端多條件篩選
- 閉包的理解
- 改變this指向
- vue單選框邏輯
- 對象數組根據某個屬性來進行排序
- vscode插件整理
- 對象數組多條件去重
- Blob類型數據轉換Json數據類型
- Element ui做批量上傳功能
- 前端cookie和后端cookie
- 強制轉換https協議
- 給事件傳額外參數
- 樹形結構數據處理
- 查找所有父級數據
- 根據id篩選單條數據
- 動態引入阿里圖標庫
- 四舍五入
- 封裝一個Promise.allSettled方法
- 判斷輸入框內是否有emoji表情
- element-ui的popover組件位置偏移
- formData上傳文件時,攜帶【數組對象參數】
- 前端解壓壓縮包(zip)解壓后上傳解壓的文件
- element ui表格列相同解決辦法
- elementUI,table復選框多選,翻頁/切換條數時保持選中狀態
- cookie 和 token 的區別