使用element-ui實(shí)現(xiàn)行合并過程
element-ui實(shí)現(xiàn)行合并過程
目標(biāo)樣式:

首先先來看下我們拿到的返回?cái)?shù)據(jù):
tableData: [
{
productType: "紡織品",
price: 123,
productName: '男裝上衣',
amount: 20,
operate_number: "20180831142020",
price: "36.00",
updateTime: "2018-08-31",
operator: "小吳"
},{
productType: "紡織品",
price: 123,
productName: '男裝褲子',
amount: 20,
operate_number: "20180831142020",
price: "36.00",
updateTime: "2018-08-31",
operator: "小吳"
},{
productType: "飲料",
price: 123,
productName: '康師傅冰紅茶',
amount: 20,
operate_number: "20180823142020",
price: "36.00",
updateTime: "2018-08-31",
operator: "小吳"
},{
productType: "紡織品",
price: 223,
productName: '男裝褲子',
amount: 10,
operate_number: "20180821142020",
price: "36.00",
updateTime: "2018-08-31",
operator: "小王"
},{
productType: "綢緞",
price: 888,
productName: '旗袍',
amount: 200,
operate_number: "20180821142020",
price: "36.00",
updateTime: "2018-08-31",
operator: "小吳"
},{
productType: "綢緞",
price: 123,
productName: '席子',
amount: 20,
operate_number: "20180821142020",
price: "36.00",
updateTime: "2018-08-31",
operator: "小吳"
},
]
我們需要將返回的數(shù)據(jù)按照該字段(operate_number)進(jìn)行處理。—— 將相同operate_number的信息的索引進(jìn)行對應(yīng)存儲。
getOrderNumber() {
let OrderObj = {}
this.tableData.forEach((element, index) => {
element.rowIndex = index
if (OrderObj[element.operate_number]) {
OrderObj[element.operate_number].push(index)
} else {
OrderObj[element.operate_number] = []
OrderObj[element.operate_number].push(index)
}
})
// 將數(shù)組長度大于1的值 存儲到this.OrderIndexArr(也就是需要合并的項(xiàng))
for (let k in OrderObj) {
if (OrderObj[k].length > 1) {
this.OrderIndexArr.push(OrderObj[k])
}
}
},
然后根據(jù)我們頁面展示需要, 控制哪一些列上的數(shù)據(jù)是需要進(jìn)行展示的。
// 合并單元格
objectSpanMethod({row,column,rowIndex,columnIndex}) {
if (columnIndex === 0 || columnIndex === 3 || columnIndex === 4) {
for (let i = 0; i < this.OrderIndexArr.length; i++) {
let element = this.OrderIndexArr[i]
for (let j = 0; j < element.length; j++) {
let item = element[j]
if (rowIndex == item) {
if (j == 0) {
return {
rowspan: element.length,
colspan: 1
}
} else if (j != 0) {
return {
rowspan: 0,
colspan: 0
}
}
}
}
}
}
},
經(jīng)過上述操作之后我們就能成功的繪制出如圖所需要的效果了。##完整代碼后面附上##
存在問題
不過這樣的話會存在一個顯示問題。就是當(dāng)我們的鼠標(biāo)滑過的時候,顯示效果不佳,如下圖所示:

?
合并后的一行數(shù)據(jù),滑過的時候效果就不對了,接下來我們就來解決一下這個問題,讓效果能達(dá)到如下圖所示:
?
關(guān)鍵詞##: cell-mouse-enter cell-mouse-leave cell-class-name
通過觸發(fā)鼠標(biāo)劃入,劃出的時候單元格的樣式:
// 單元格樣式
tableRowClassName({row,rowIndex}) {
let arr = this.hoverOrderArr
for (let i = 0; i < arr.length; i++) {
if (rowIndex == arr[i]) {
return 'hovered-row'
}
}
},
// 鼠標(biāo)劃入,劃出效果
cellMouseEnter(row, column, cell, event) {
this.rowIndex = row.rowIndex;
this.hoverOrderArr = [];
this.OrderIndexArr.forEach(element => {
if (element.indexOf(this.rowIndex) >= 0) {
this.hoverOrderArr = element
}
})
},
cellMouseLeave(row, column, cell, event) {
this.rowIndex = '-1'
this.hoverOrderArr = [];
}
附上完整代碼
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>element-ui實(shí)現(xiàn)合并單元格效果</title>
<link rel="external nofollow" rel="stylesheet">
<style>
.el-table .hovered-row {
background: #f5f7fa;
}
</style>
</head>
<body>
<div id="app">
<el-table ref="multipleTable" border :span-method="objectSpanMethod" :cell-class-name="tableRowClassName"
@cell-mouse-leave="cellMouseLeave" @cell-mouse-enter="cellMouseEnter" :data="tableData" style="width: 80%;margin:0 auto;">
<el-table-column label="商品類別" align="center">
<template slot-scope="scope" width="160">
<div>{{scope.row.productType}}</div>
</template>
</el-table-column>
<el-table-column label="商品價格" align="center">
<template slot-scope="scope">
<p>{{scope.row.price}}</p>
</template>
</el-table-column>
<el-table-column label="商品名稱" width="180px" align="center">
<template slot-scope="scope">
<p>{{scope.row.productName}}</p>
</template>
</el-table-column>
<el-table-column label="操作人員" align="center">
<template slot-scope="scope">
<p>{{scope.row.operator}}</p>
</template>
</el-table-column>
<el-table-column prop="updateTime" label="更新時間" align="center">
</el-table-column>
</el-table>
</div>
</body>
<script src="https://cdn.jsdelivr.net/npm/vue/dist/vue.js"></script>
<script src="https://unpkg.com/element-ui/lib/index.js"></script>
<script>
new Vue({
el: '#app',
data: {
tableData: [
{
productType: "紡織品",
price: 123,
productName: '男裝上衣',
amount: 20,
operate_number: "20180831142020",
price: "36.00",
updateTime: "2018-08-31",
operator: "小吳"
},{
productType: "紡織品",
price: 123,
productName: '男裝褲子',
amount: 20,
operate_number: "20180831142020",
price: "36.00",
updateTime: "2018-08-31",
operator: "小吳"
},{
productType: "飲料",
price: 123,
productName: '康師傅冰紅茶',
amount: 20,
operate_number: "20180823142020",
price: "36.00",
updateTime: "2018-08-31",
operator: "小吳"
},{
productType: "紡織品",
price: 223,
productName: '男裝褲子',
amount: 10,
operate_number: "20180821142020",
price: "36.00",
updateTime: "2018-08-31",
operator: "小王"
},{
productType: "綢緞",
price: 888,
productName: '旗袍',
amount: 200,
operate_number: "20180821142020",
price: "36.00",
updateTime: "2018-08-31",
operator: "小吳"
},{
productType: "綢緞",
price: 123,
productName: '席子',
amount: 20,
operate_number: "20180821142020",
price: "36.00",
updateTime: "2018-08-31",
operator: "小吳"
},
],
rowIndex: '-1',
OrderIndexArr: [],
hoverOrderArr: []
},
mounted() {
this.getOrderNumber()
},
methods: {
// 獲取相同編號的數(shù)組
getOrderNumber() {
let OrderObj = {}
this.tableData.forEach((element, index) => {
element.rowIndex = index
if (OrderObj[element.operate_number]) {
OrderObj[element.operate_number].push(index)
} else {
OrderObj[element.operate_number] = []
OrderObj[element.operate_number].push(index)
}
})
// 將數(shù)組長度大于1的值 存儲到this.OrderIndexArr(也就是需要合并的項(xiàng))
for (let k in OrderObj) {
if (OrderObj[k].length > 1) {
this.OrderIndexArr.push(OrderObj[k])
}
}
},
// 合并單元格
objectSpanMethod({row,column,rowIndex,columnIndex}) {
if (columnIndex === 0 || columnIndex === 3 || columnIndex === 4) {
for (let i = 0; i < this.OrderIndexArr.length; i++) {
let element = this.OrderIndexArr[i]
for (let j = 0; j < element.length; j++) {
let item = element[j]
if (rowIndex == item) {
if (j == 0) {
return {
rowspan: element.length,
colspan: 1
}
} else if (j != 0) {
return {
rowspan: 0,
colspan: 0
}
}
}
}
}
}
},
tableRowClassName({row,rowIndex}) {
let arr = this.hoverOrderArr
for (let i = 0; i < arr.length; i++) {
if (rowIndex == arr[i]) {
return 'hovered-row'
}
}
},
cellMouseEnter(row, column, cell, event) {
this.rowIndex = row.rowIndex;
this.hoverOrderArr = [];
this.OrderIndexArr.forEach(element => {
if (element.indexOf(this.rowIndex) >= 0) {
this.hoverOrderArr = element
}
})
},
cellMouseLeave(row, column, cell, event) {
this.rowIndex = '-1'
this.hoverOrderArr = [];
}
}
})
</script>
</html>
element-ui合并單元格行處理方法
在平時開發(fā)過程中經(jīng)常涉及到行、列單元格的合并,本文記錄LZ使用方式,只涉及到行的合并(場景較多),列也可同理而得
獲取合并規(guī)則
/**
* 合并單元格
* @param tableData table數(shù)據(jù) []
* @param spans 待合并 property
* eg:[{key:'country'},{key:'year',rely:'country'}], rely表依賴,是否依賴前置列
* @returns {{}}
*/
getMergeSpan(tableData,spans){
let rowMerge = {},obj = {}
for(let i = 0;i<spans.length;i++){
let property = spans[i].key
let rely = spans[i].rely
let total = 1 , start = 0
tableData.forEach((item,index)=>{
let nextRow = tableData[index+1] || {}
let isComRely = rely ? item[rely] === nextRow[rely] : true
if(item[property] === nextRow[property] && isComRely){
total ++
}else{
obj[start] = total
start = index + 1
total = 1
}
})
rowMerge[property] = obj
obj = {}
}
return rowMerge
},elemen-ui span-method 合并方式
/**
* element-ui 合并方法
* @param row 行 數(shù)據(jù)
* @param column 列信息
* @param rowIndex 行號
* @param columnIndex 列號
* @returns {(*|number)[]|number[]}
*/
tableMergeMethod({ row, column, rowIndex, columnIndex }) {
if(columnIndex === 0){ //tip: 列位置 須根據(jù)el-table-column獲取
let total = this.tableMerge['country'][rowIndex]
if(total){
return [total,1]
}else {
return [0,0]
}
}
if(columnIndex === 1){
let total = this.tableMerge['year'][rowIndex] // tableMerge:通過getMergeSpan獲取的規(guī)則
if(total){
return [total,1]
}else {
return [0,0]
}
}
},eg:
this.tableMerge = getMergeSpan(this.tableData,[{key:'country'},{key:'year',rely:'country'}])合并效果

以上為個人經(jīng)驗(yàn),希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
vue項(xiàng)目搭建以及全家桶的使用詳細(xì)教程(小結(jié))
這篇文章主要介紹了vue項(xiàng)目搭建以及全家桶的使用詳細(xì)教程(小結(jié)),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-12-12
解決router.beforeEach()動態(tài)加載路由出現(xiàn)死循環(huán)問題
這篇文章主要介紹了解決router.beforeEach()動態(tài)加載路由出現(xiàn)死循環(huán)問題,具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教2022-10-10
vue基于element-china-area-data插件實(shí)現(xiàn)省市區(qū)聯(lián)動
省市區(qū)聯(lián)動在日常開發(fā)中用的非常多,本文就介紹一下vue基于element-china-area-data插件實(shí)現(xiàn)省市區(qū)聯(lián)動,具有一定的參考價值,感興趣的可以了解一下2022-04-04
解決ant Design中Select設(shè)置initialValue時的大坑
這篇文章主要介紹了解決ant Design中Select設(shè)置initialValue時的大坑,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2020-10-10
vue3+ts中ref與reactive指定類型實(shí)現(xiàn)示例
這篇文章主要為大家介紹了vue3+ts中ref及reactive如何指定類型的實(shí)現(xiàn)示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-06-06
vue自定義標(biāo)簽和單頁面多路由的實(shí)現(xiàn)代碼
這篇文章主要介紹了vue自定義標(biāo)簽和單頁面多路由的實(shí)現(xiàn)代碼,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下2020-05-05

