iview4.0,table组件合并单元格初体验

心心念念

念念不忘,必有回响!iview4.0终于出了合并单元格的功能,喜极而泣,最近的项目全是各种表格,正好有此需求,之前项目用的3.4.2版本,在iview官网上看到span-method功能,然后就升级升级升级!
链接: https://www.iviewui.com/components/table#GDBT.
源码: https://gitee.com/penny0906/blog-files/blob/master/sonReportTable.vue.

基本思路

span-method对应的函数返回的是单元格占据的行列,然后就如果存在一个跟表格内容一一对应的行列的二维数组layout,根据当前参数rowIndex, columnIndex,返回layout[rowIndex][columnIndex],这样就方便多了,所有的代码都是为了得到这个layout数组!

实现合并

1.后台返回的数据一般长这样:
一个数组,每一项里包含key,value
iview4.0,table组件合并单元格初体验_第1张图片
2.期待的layout
我们想得到的layout长这样,一个布局数组iview4.0,table组件合并单元格初体验_第2张图片
3.实现
代码片.

handleSpan({ row, column, rowIndex, columnIndex }) {
            // 合并单元格
            return this.layout[rowIndex][columnIndex];
        },
getLayOut() {
            // 获取布局数组
            // 得到一个跟布局数组结构一样的相对应的表格value值数组
            const arr = [];
            let columnsKey = this.getOrderColumnsKey(this.tableOptions.columns, []);
            this.tableOptions.data.forEach(it => {
                arr.push([]);
                columnsKey.forEach(key => {
                    arr[arr.length - 1].push(it[key]);
                });
            });

            // 得到一个普通的布局数组
            this.layout = [];
            arr.forEach(item => {
                this.layout.push([]);
                item.forEach(it => {
                    this.layout[this.layout.length - 1].push([1, 1]);
                });
            });

            // 得到一个合并单元格布局数组
            for (let i = 0; i < this.layout.length; i++) {
                for (let j = 0; j < this.tableOptions.reportLength; j++) {
                    const target = this.layout[i][j];
                    if (target[0] * target[1] !== 0) {
                        // 向下合并
                        for (let k = i + 1; k < this.layout.length; k++) {
                            if (arr[i][j] === arr[k][j]) {
                                target[0] += 1;
                                this.layout[k][j] = [0, 0];
                            } else {
                                break;
                            }
                        }
                        // 向右合并
                        for (let k = j + 1; k < this.layout[i].length; k++) {
                            if (arr[i][j] === arr[i][k]) {
                                target[1] += 1;
                                this.layout[i][k] = [0, 0];
                            } else {
                                break;
                            }
                        }
                    }
                }
            }
        },
 getOrderColumnsKey(list, arr) {
            // 获取多级columns平铺的key值,变为一维数组
            list.forEach((it, index) => {
                if (it.key) {
                    arr.push(it.key);
                } else {
                    arr.push([]);
                    this.getOrderColumnsKey(it.children, arr[index]);
                }
            });
            return arr.flat(Infinity);
        }

补充:
1)this.tableOptions是我的表格配置项;
2)columnsKey 是当前表格显示的key值数组,从左到右,顺序必须对;不是后台返回的key值顺序,是前端页面显示的顺序!
因为我这个表头层级比较多,所以写了个getOrderColumnsKey方法把key值取出来了,可以参考;
3)this.tableOptions.reportLength这个参数是你需要几列做这个合并操作,就填几,我的表格只要前两列做合并,后面都是数值,不需要做合并了,我传的参数是2;
4)这个逻辑是字段的value值重复就会合并,让后台尽量给一个合适的结构,参考第一张图;
5)这个方法有一点需要注意,如果你第一组和第二组内容列有重复的地方,此处也会进行合并,如果希望每组内容自己独立,不合并别组内容,可以根据原数据自己定义一个以组为区别的新的数组,作为判断是否合并的依据数组,具体解决方法参考源码this.newData就是以groupName字段相互区别的新数组,如果没有此困扰,可以忽略这一条;

4.最终效果
iview4.0,table组件合并单元格初体验_第3张图片
5.希望对你有所帮助,菜鸡的第一篇博客记录,留爪!如有雷同想法,纯属巧合!

你可能感兴趣的:(vue.js,javascript)