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

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

vue+elemet实现表格手动合并行列的更多相关文章

  1. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  2. vue自定义加载指令v-loading占位图指令v-showimg

    这篇文章主要为大家介绍了vue自定义加载指令和v-loading占位图指令v-showimg的示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

  3. vue使用动画实现滚动表格效果

    这篇文章主要为大家详细介绍了vue使用动画实现滚动表格效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  4. 关于Vue 监控数组的问题

    这篇文章主要介绍了Vue 监控数组的示例,主要包括Vue 是如何追踪数据发生变化,Vue 如何更新数组以及为什么有些数组的数据变更不能被 Vue 监测到,对vue监控数组知识是面试比较常见的问题,感兴趣的朋友一起看看吧

  5. Vue子组件props从父组件接收数据并存入data

    这篇文章主要介绍了Vue子组件props从父组件接收数据并存入data的方法,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

  6. Vue h函数的使用详解

    本文主要介绍了Vue h函数的使用详解,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  7. VUE响应式原理的实现详解

    这篇文章主要为大家详细介绍了VUE响应式原理的实现,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助

  8. vue+Element ui实现照片墙效果

    这篇文章主要为大家详细介绍了vue+Element ui实现照片墙效果,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

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

    这篇文章主要为大家详细介绍了vue+elemet实现表格手动合并行列,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. node下使用UglifyJS压缩合并JS文件的方法

    下面小编就为大家分享一篇node下使用UglifyJS压缩合并JS文件的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧

随机推荐

  1. js中‘!.’是什么意思

  2. Vue如何指定不编译的文件夹和favicon.ico

    这篇文章主要介绍了Vue如何指定不编译的文件夹和favicon.ico,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教

  3. 基于JavaScript编写一个图片转PDF转换器

    本文为大家介绍了一个简单的 JavaScript 项目,可以将图片转换为 PDF 文件。你可以从本地选择任何一张图片,只需点击一下即可将其转换为 PDF 文件,感兴趣的可以动手尝试一下

  4. jquery点赞功能实现代码 点个赞吧!

    点赞功能很多地方都会出现,如何实现爱心点赞功能,这篇文章主要为大家详细介绍了jquery点赞功能实现代码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  5. AngularJs上传前预览图片的实例代码

    使用AngularJs进行开发,在项目中,经常会遇到上传图片后,需在一旁预览图片内容,怎么实现这样的功能呢?今天小编给大家分享AugularJs上传前预览图片的实现代码,需要的朋友参考下吧

  6. JavaScript面向对象编程入门教程

    这篇文章主要介绍了JavaScript面向对象编程的相关概念,例如类、对象、属性、方法等面向对象的术语,并以实例讲解各种术语的使用,非常好的一篇面向对象入门教程,其它语言也可以参考哦

  7. jQuery中的通配符选择器使用总结

    通配符在控制input标签时相当好用,这里简单进行了jQuery中的通配符选择器使用总结,需要的朋友可以参考下

  8. javascript 动态调整图片尺寸实现代码

    在自己的网站上更新文章时一个比较常见的问题是:文章插图太宽,使整个网页都变形了。如果对每个插图都先进行缩放再插入的话,太麻烦了。

  9. jquery ajaxfileupload异步上传插件

    这篇文章主要为大家详细介绍了jquery ajaxfileupload异步上传插件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

  10. React学习之受控组件与数据共享实例分析

    这篇文章主要介绍了React学习之受控组件与数据共享,结合实例形式分析了React受控组件与组件间数据共享相关原理与使用技巧,需要的朋友可以参考下

返回
顶部