目标样式:
首先先来看下我们拿到的返回数据:
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: "小吴"
},
]
我们需要将返回的数据按照该字段(operate_number)进行处理。—— 将相同operate_number的信息的索引进行对应存储。
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)
}
})
// 将数组长度大于1的值 存储到this.OrderIndexArr(也就是需要合并的项)
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
}
}
}
}
}
}
},
经过上述操作之后我们就能成功的绘制出如图所需要的效果了。##完整代码后面附上##
存在问题
不过这样的话会存在一个显示问题。就是当我们的鼠标滑过的时候,显示效果不佳,如下图所示:

合并后的一行数据,滑过的时候效果就不对了,接下来我们就来解决一下这个问题,让效果能达到如下图所示:

关键词##: cell-mouse-enter cell-mouse-leave cell-class-name
通过触发鼠标划入,划出的时候单元格的样式:
// 单元格样式
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 = [];
}
附上完整代码
<!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实现合并单元格效果</title>
<link href="https://unpkg.com/element-ui/lib/theme-chalk/index.css" 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: {
// 获取相同编号的数组
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)
}
})
// 将数组长度大于1的值 存储到this.OrderIndexArr(也就是需要合并的项)
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>