element-ui实现行合并过程
存在问题
关键词##: cell-mouse-enter cell-mouse-leave cell-class-name
element-ui合并单元格行处理方法
获取合并规则
elemen-ui span-method 合并方式
合并效果
element-ui实现行合并过程目标样式:
首先先来看下我们拿到的返回数据:
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="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: {
// 获取相同编号的数组
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>
element-ui合并单元格行处理方法
在平时开发过程中经常涉及到行、列单元格的合并,本文记录LZ使用方式,只涉及到行的合并(场景较多),列也可同理而得
获取合并规则 /**
* 合并单元格
* @param tableData table数据 []
* @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 行 数据
* @param column 列信息
* @param rowIndex 行号
* @param columnIndex 列号
* @returns {(*|number)[]|number[]}
*/
tableMergeMethod({ row, column, rowIndex, columnIndex }) {
if(columnIndex === 0){ //tip: 列位置 须根据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获取的规则
if(total){
return [total,1]
}else {
return [0,0]
}
}
},
eg:
this.tableMerge = getMergeSpan(this.tableData,[{key:'country'},{key:'year',rely:'country'}])
合并效果
以上为个人经验,希望能给大家一个参考,也希望大家多多支持软件开发网。