好得很程序员自学网

<tfoot draggable='sEl'></tfoot>

vue+elemet实现表格手动合并行列

本文实例为大家分享了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>

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。

查看更多关于vue+elemet实现表格手动合并行列的详细内容...

  阅读:35次