本篇内容介绍了“怎么用vue+elemet实现表格手动合并行列”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
1.初始化一个element的table表格,选中一个单元格选择合并行和列,参考element文档需要使用到的方法是objectSpanMethod,注意:objectSpanMethod参数行和列都是从0开始,比如第一行第一列单元格位置是(0,0),要合并的行和列最小为1
2.实现效果如下:
3.代码如下:
<template> <div class="content"> <div class="table_box" v-if="show"> <el-table ref="singleTable" :data="tableData" highlight-current-row @current-change="handleCurrentChange" border :span-method="objectSpanMethod" @cell-dblclick = "dbclick" :cell-class-name="tableCellClassName" @cell-click="cellClick" > <el-table-column v-for="(item,key,index) in tableColumns" :key="index" :label="item.label" :prop="item.children?'':item.prop" width="180"> <el-popover placement="right" width="400" slot-scope="scope" trigger="click"> <el-button size="mini" type="primary" @click="dialogVisible = true">合并单元格</el-button> <el-button size="mini" type="primary" @click="addTr('top',selectTab.tr)">向上插入一行</el-button> <el-button size="mini" type="primary" @click="addTr('bottom',selectTab.tr)">向下插入一行</el-button> <div slot="reference"> <span>{{ scope.row[item.prop] }}</span> </div> </el-popover> <div v-if="item.children && item.children.length>0"> <el-table-column v-for="(val,i) in item.children" :key="i" :prop="val.prop" :label="val.label" width="180"> <!-- <template slot-scope="scope"> <span>{{ scope.row[val.prop] }}22</span> </template> --> <el-popover placement="right" width="400" slot-scope="scope" trigger="click"> <el-button size="mini" type="primary" @click="dialogVisible = true">合并单元格</el-button> <el-button size="mini" type="primary" @click="addTr('top',selectTab.tr)">向上插入一行</el-button> <el-button size="mini" type="primary" @click="addTr('bottom',selectTab.tr)">向下插入一行</el-button> <div slot="reference"> <span>{{ scope.row[val.prop] }}</span> </div> </el-popover> </el-table-column> </div> </el-table-column> </el-table> </div> <el-dialog title="合并" :visible.sync="dialogVisible" width="300px" > <el-form ref="form" label-width="80px"> <el-form-item label="合并行"> <el-input :min="0" v-model="selectTab.trSpan"/> </el-form-item> <el-form-item label="合并列"> <el-input :min="0" v-model="selectTab.tdSpan"/> </el-form-item> </el-form> <span slot="footer" class="dialog-footer"> <el-button @click="dialogVisible = false" size="small">取 消</el-button> <el-button type="primary" @click="addMerge" size="small">确 定</el-button> </span> </el-dialog> </div> </template> <script> export default { data(){ return{ tableData:[],//表格数据 tableColumns:[],//表头数据 show:false, currentRow: null, spanArr:[], selectTab:{ tr:0,//第几行 td:0,//第几列 trSpan:1,//占几行 tdSpan:1,//占几列 }, mergeList:[],//记录合并详情 dialogVisible:false, } }, watch:{ // mergeList:{//监听合并列表项 // handler(newVal,oldVal){ // console.log('刷新'); // this.show = false; // this.$nextTick(()=>{ // this.show = true; // }) // }, // deep:true // } }, mounted(){ this.init(); }, methods:{ tableCellClassName({row, column, rowIndex, columnIndex}){ //注意这里是解构 //利用单元格的 className 的回调方法,给行列索引赋值 row.index=rowIndex; column.index=columnIndex; }, cellClick(row, column, cell, event){ console.log('rowIndex',row.index); console.log('colIndex',column.index); this.selectTab.tr = row.index+1; this.selectTab.td = column.index+1; }, dbclick(row, column, cell, event){ console.log('row:',row); console.log('column:',column,); console.log('cell:',cell); console.log('event:',event); this.selectTab.tr = row.index+1; this.selectTab.td = column.index+1; }, addMerge(){//合并项添加进合并列表中 // let obj = this.mergeList.filter(item=>item.td==this.selectTab.td&&item.tr) let flag = false; let w = -1; this.mergeList.forEach((item,index)=>{ if(item.td==this.selectTab.td && item.tr==this.selectTab.tr){//是否有重复项,有则替换 flag = true; w = index; } }) if(flag){ this.mergeList[w] = Object.assign({},this.selectTab); }else{ this.mergeList.push(Object.assign({},this.selectTab)); } this.dialogVisible = false; this.show = false;//手动刷新 this.$nextTick(()=>{ this.show = true; }) }, objectSpanMethod({ row, column, rowIndex, columnIndex }) {//表格的合并函数 //console.log('列',columnIndex,rowIndex); //console.log('行',row,column);0,2 // let td = Number(this.selectTab.td)-1;//columnIndex从0开始 // let tr = Number(this.selectTab.tr)-1;//rowIndex从0开始 // if( columnIndex>=td && columnIndex<=((Number(td)+Number(this.selectTab.trSpan))-1)){ // if( rowIndex>=tr && rowIndex<=((Number(tr)+Number(this.selectTab.tdSpan))-1)){ // if(columnIndex==td && rowIndex==tr){ // return [this.selectTab.tdSpan,this.selectTab.trSpan] // }else{ // console.log('选择的行列',columnIndex,rowIndex); // console.log('选择的列',this.selectTab.td,(Number(this.selectTab.td)+Number(this.selectTab.tdSpan))-1); // console.log('选择的行',this.selectTab.tr,(Number(this.selectTab.tr)+Number(this.selectTab.trSpan))-1); // return [0,0] // } // } // } if(this.mergeList.length>0){ console.log('merge',this.mergeList); for(let i=0;i<this.mergeList.length;i++){ let item = this.mergeList[i]; let td = Number(item.td)-1;//columnIndex从0开始 let tr = Number(item.tr)-1;//rowIndex从0开始 if( columnIndex>=td && columnIndex<=((Number(td)+Number(item.trSpan))-1)){ if( rowIndex>=tr && rowIndex<=((Number(tr)+Number(item.tdSpan))-1)){ if(columnIndex==td && rowIndex==tr){ console.log('选中的行列',columnIndex,rowIndex,item.tdSpan,item.trSpan); return [item.tdSpan,item.trSpan] }else{ console.log('选择的行列',columnIndex,rowIndex); // console.log('选择的列',this.selectTab.td,(Number(this.selectTab.td)+Number(this.selectTab.tdSpan))-1); // console.log('选择的行',this.selectTab.tr,(Number(this.selectTab.tr)+Number(this.selectTab.trSpan))-1); return [0,0] } } } } } //forEach中使用return不会中断,相当于continue // this.mergeList.forEach(item=>{ // let td = Number(item.td)-1;//columnIndex从0开始 // let tr = Number(item.tr)-1;//rowIndex从0开始 // if( columnIndex>=td && columnIndex<=((Number(td)+Number(item.trSpan))-1)){ // if( rowIndex>=tr && rowIndex<=((Number(tr)+Number(item.tdSpan))-1)){ // if(columnIndex==td && rowIndex==tr){ // console.log('选中的行列',columnIndex,rowIndex,item.tdSpan,item.trSpan); // return [item.tdSpan,item.trSpan] // }else{ // console.log('选择的行列',columnIndex,rowIndex); // // console.log('选择的列',this.selectTab.td,(Number(this.selectTab.td)+Number(this.selectTab.tdSpan))-1); // // console.log('选择的行',this.selectTab.tr,(Number(this.selectTab.tr)+Number(this.selectTab.trSpan))-1); // return [0,0] // } // } // } // }) }, init(){//初始化表格 // if(this.tdCount==0){ // this.tableColumns = [{label:'默认',prop:'default'}]; // this.tableData = [{default:0}]; // } this.tableColumns = [ {label:'默认',prop:'default'}, {label:'双十一',prop:'',children:[{label:'库存',prop:'count'},{label:'销量',prop:'sale'}]}, ]; this.tableData = [ {default:0,count:111,sale:100}, {default:0,count:173,sale:220}, {default:0,count:89,sale:120} ]; this.show = true; }, addTab(){//插入表头 if(this.tableColumns.every(item=>item.label!=this.tab.label)){ this.tableColumns.push(Object.assign({},this.tab)); }else{ this.$notify.error({ title: '错误', message: '表头重复' }); } }, addTr(way,index){//插入一行数据 let obj = {}; // this.tableColumns.forEach(item=>{ // obj[item.prop] = Math.floor(Math.random()*100); // }) obj = this.getObj(this.tableColumns,obj); console.log('obj',obj); if(way=='top'){//在第index行之前插入一行 this.tableData.splice(index-1,0,obj); }else{在第index行之后插入一行 this.tableData.splice(index,0,obj); } }, getObj(tabs,obj){ tabs.forEach(item=>{ if(item.children){ this.getObj(item.children,obj); }else{ obj[item.prop] = Math.floor(Math.random()*100); } }) return obj; }, setCurrent(row) { this.$refs.singleTable.setCurrentRow(row); }, handleCurrentChange(val) {//点击行事件 console.log('val',val); this.currentRow = val; }, } } </script> <style scoped> </style>