element-ui实现行合并
小白变怪兽 人气:0element-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'}])
合并效果
以上为个人经验,希望能给大家一个参考,也希望大家多多支持。
加载全部内容