在之前的项目中,我接到一个需求,需要一个类似excel的表格合并和拆分的需求。
目前我自己初步实现是这样子的
在这里插入图片描述
我们的项目是前后分离的,后端用的是.net,前端用的是vue,得到这个需求之后,我的第一反应是网上找找能不能找到类似的功能代码,但是很可惜的是我并没有找到。所以只能自己尝试着写
在这里插入图片描述
思前想后,只能从table的数据结构入手,所以我就尝试着写一个table的数据结构,然后vue的table在element中有固定的模板,我们之前都是用这个直接套用的,现在我发现用这个很难实现这个需求,所以又只能自己用原生的<table>、<tr>、<td>colspanrowspan来实现。

这里首先,要感谢我的前端大佬同事,是这位大佬帮我实现了如此复杂的需求逻辑
(ps 真实项目中比我这里写的复杂很多哦~~)

首先,先定义table的数据结构,根据渲染格式我是写了一个方法里面来设置table的数据结构
在这里插入图片描述
在这里插入图片描述
走到这一步的时候,我们已经实现了最基础的table表格了
在这里插入图片描述
剩下的,我们需要在每一个单元格后面加一个按钮来实现合并、拆分的需求,这里我就直接用了elelment里面的组件(https://element.eleme.cn/#/zh-CN/component/installation
在这里插入图片描述
我们仿照组件里面的demo写法复制过来稍加修改
在这里插入图片描述
到了这一步,我们的全部外观展示以及完成了
在这里插入图片描述
下面我们要开始最难的部分看了,实现拆分、合并的代码需求。
我们在<el-dropdown>组面里面的@command="handleCommand"方法里面写上面的定义的不同方法。

handleCommand(val) {
            //定位行列
            let trIndex = val.pIndex;
            let tdIndex = val.cellObject.index;
            // 行数据
            let trObject = this.trData[trIndex].child;
            // 列数据
            let tdObject = this.trData[val.pIndex].child[tdIndex];
            //  向后合并
            if (val.type == "afterMerge") {
                // 最后一个单元格不给向后合并
                if (tdIndex == this.trData[trIndex].child.length - 1) {
                    this.$message({
                        message: "此单元格后无可合并的项",
                        type: "warning"
                    });
                    return false;
                }
                if (tdObject.occupyRow != trObject[tdIndex + 1].occupyRow) {
                    this.$message.warning("格式不同不能合并");
                    return false;
                } else {
                    // 合并行数加上下一个单元格的列
                    tdObject.occupyCol += trObject[tdIndex + 1].occupyCol;
                    // 删除后一项
                    trObject.splice(tdIndex + 1, 1);
                }
            }
            //向后拆分 插入的单元格 跨列数为1
            if (val.type == "afterSplit") {
                if (tdObject.occupyCol == 1) {
                    this.$message({
                        message: "此单元格前无可拆分的项",
                        type: "warning"
                    });
                    return false;
                } else {
                    this.cellObject.occupyRow = tdObject.occupyRow;
                    // 单元格列减1
                    tdObject.occupyCol--;
                    let newObject = {};
                    newObject.index = this.cellObject.index;
                    newObject.name = this.cellObject.name;
                    newObject.label = this.cellObject.label;
                    newObject.occupyCol = 1;
                    newObject.occupyRow = this.cellObject.occupyRow;
                    trObject.splice(tdIndex + 1, 0, newObject);
                }
            }
            //全部单元格索引重排
            this.newSort();
        },
        newSort() {
            this.trData.forEach((el, i) => {
                el.index = i;
                el.child.forEach((al, j) => {
                    al.index = j;
                    al.label = j;
                });
            });
        }

上面的一串代码也就是实现的具体逻辑了,相信聪明的小伙伴们一定能看懂的(几乎主要的都有注释~)。

大功告成!!!
在这里插入图片描述

初次写博客文章,不怎么会写。。。
就这样吧。
demo源码需要的话可以到我的博客资源内下载,或者下面回复想要源码。

Logo

魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。

更多推荐