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>

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

(0)

相关推荐

  • vue.js实现表格合并示例代码

    前言 由于使用的是vue,想到MVVM是要用数据驱动的思想,所以考虑在Model做手脚,而不是渲染出数据来后做DOM操作,当然基本的CSS还是要有的.因此这个方法对所有数据驱动的框架都有效,比如说Angular和React. 最后的实现效果是这样的: 实现思路 原本的正常表格的代码长这样: <tr v-for="item in items"> <td width="3%">{{ $index + 1 }}</td> <td

  • vue实现表格合并功能

    本文实例为大家分享了vue实现表格合并功能的具体代码,供大家参考,具体内容如下 1.背景 本身有vue进行渲染的数据表格,,但是出于整体考虑,需要对相同的列信息进行单元格合并. 由于使用的是vue,想到MVVM是要用数据驱动的思想,所以考虑在Model做手脚,而不是渲染出数据来后做DOM操作,当然基本的CSS还是要有的.因此这个方法对所有 数据驱动的框架都有效,比如说Angular和React.最后的实现效果是这样的: 2.思路 原本的正常表格是这样的: <table > <thead&

  • Vue实现数据表格合并列rowspan效果

    背景 现实中会遇到很多需求,合并列,例如要显示一个名学生的各门课程成绩. html实现 使用html实现是比较简单的,利用table标签的rowspan属性即可,代码如下: <table> <thead> <tr> <th>姓名</th> <th>课程数</th> <th>课程名称</th> <th>成绩</th> </tr> </thead> <

  • Vue Elenent实现表格相同数据列合并

    本文实例为大家分享了Vue Elenent实现表格相同数据列合并的具体代码,供大家参考,具体内容如下 作者:秋名 思路:后台查询表格数据,查询出来后直接传到前端,前端通过foreach循环,然后对相同的表格进行合并.(同一个表格,但是每一行,固定一列的数据都相同,即可使用合并单元格,做到了既美观,也清晰.) template: <el-table :span-method="objectSpanMethod4" //在el-table里面添加合并单元格属性 > Js: da

  • ant-design-vue动态表格合并案例

    目录 前言 数据格式 ant-desgin-vue表格提供的api 合并单元格算法实现 效果展示 前言 最近接到一个需求,要把后端传过来的数据动态展示在表格上面,并且支持前端筛选,相同数据进行单元格合并, 最终实现的效果如下: 数据格式 后端会返回给我们一个数组,数组的每一项格式是这样,在这个需求里,我们需要对 title,department,bugType 这三个字段相同的值的单元格进行合并 { fixCount: 0, id: 0, codeType: '新代码', bugType: 'u

  • vue element实现表格合并行数据

    本文实例为大家分享了vue element实现表格合并行数据的具体代码,供大家参考,具体内容如下 支持不分页的表格数据,分页的表格数据还有小bug <template> <el-container> <el-main> <el-table :data="tableData" border style="width: 100%" :span-method="objectSpanMethod" //添加这个实

  • vue通过数据过滤实现表格合并

    基于vue通过数据过滤实现表格合并,供大家参考,具体内容如下 需求 基于vue渲染的数据表格 需要对相同的列进行合并 思路 自从使用了vue,就再也不想直接操作dom节点了,所以还是对数据操作. 要合并单元格需要用到rowspan属性,所有想法是针对数据添加rowspan属性使其多行显示,但下面的行再去渲染就重复了,所以用hidden 隐藏掉. 所以,针对每一行数据 ,用rowspan和display来控制每一个单元格的合并行数和是否显示 代码 <table id="search_tabl

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

    本文实例为大家分享了vue+elemet实现表格手动合并行列的具体代码,供大家参考,具体内容如下 1.初始化一个element的table表格,选中一个单元格选择合并行和列,参考element文档需要使用到的方法是objectSpanMethod,注意:objectSpanMethod参数行和列都是从0开始,比如第一行第一列单元格位置是(0,0),要合并的行和列最小为1 2.实现效果如下: 3.代码如下: <template>     <div class="content&q

  • el-table表格动态合并行及合并行列实例详解

    目录 前言 1.合并行 2.合并行列 总结 前言 在写项目的时候有时候会经常遇到把行和列合并起来的情况,因为有些数据是重复渲染的,不合并行列会使表格看起来非常的混乱,如下: 而我们想要的数据是下面这种情况,将重复的行进行合并,使表格看起来简单明了,如下: 1.合并行 所谓的合并行就是将多行相同的数据变成一行来显示,直接上代码,页面的布局比较简单 <template> <div class="table"> <el-table :data="tab

  • C#使用Npoi导出Excel并合并行列

    在工作开发中,客户经常要求数据库中数据导出到Excel表格.以前方法是引用office相关组件,如果客户没有安装office,功能就会遇到问题. 现在用Npoi导出Excel,导出表格是合并行列,如图: 导出的要求:合计列要进行合并,序号一致的要合并.最后一行要合并列.因为相同序号数量不是固定的,要动态算合并的行数. 合并行列接口:XXX.AddMergedRegion(new CellRangeAddress(开始行, 最后一行, 开始列, 最后一列)); 隐藏指定:sheet.SetColu

  • vue引入Excel表格插件的方法

    本文实例为大家分享了vue引入Excel表格插件的具体代码,供大家参考,具体内容如下 一.安装 npm install handsontable-pro @handsontable-pro/vue npm install handsontable @handsontable/vue 二.引用(在页面引用) import { HotTable } from '@handsontable-pro/vue' import '-/-/node_modules/handsontable-pro/dist/

  • Vue+jquery实现表格指定列的文字收缩的示例代码

    本文介绍了Vue+jquery实现表格指定列的文字收缩的示例代码,分享给大家,具体如下: 效果很简单,但是写起来真的不容易,因为Vue对于没有React这种前端框架经验的人是不友好的 (少吐槽,多工作,省下时间出去hi) 先说一下我走过的弯路:我之间想通过 v-if 指令去操作这一列 代码是这样的: <el-table-column width="250" align="center" label="比较基准"> <templa

  • 利用vue + element实现表格分页和前端搜索的方法

    前言 ElementUI是饿了么前端开源的一个基于Vue的前端框架,已经帮我们封装好了一系列功能性的组件,比如栅格系统.表格.表单.树形菜单.通知等.对于搞后台管理界面的项目,特别是不需要考虑兼容ie8.ie9以下的项目.ElementUI是一个不错的选择. 而且ElementUI的文档写得十分详尽,参照demo可以很快上手. 本文主要介绍了关于vue + element实现表格分页和前端搜索的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧. 实现思路 1.前端后台管理

  • vue elementUI table表格数据 滚动懒加载的实现方法

    在项目中遇到了一个性能问题 vue+elementUI table表格展示数据,当数据很多的时候,不能一页显示完,同时一次请求数据量太大,会增加网页渲染的时间,影响体验, 这个时候常常有两种方法处理, 1.分页,如下 2.如果我不想分页,又想在一页显示全部数据呢?这个时候其实就可以用数据懒加载了 如下一开始表格只显示31行数据 当将滚动条拉到低的时候,就会再加载31条数据,如果剩下的数据不足31,那就加载剩下的 根据项目需求,这需要一页可以看到全部数据,所以我选择了第二中方式 那么第二种方式要怎

  • vue实现动态表格提交参数动态生成控件的操作

    上面要求做一个根据后台数据动态生成控件,然后让用户输入提交查询信息,然后动态生成表格在显示出来.动态控件代码如下 <el-form :model="formData" style="padding: 0 5px;"> <div v-if="tableshow"> <div v-for="(item,i) in control" :key="i" style="padd

随机推荐