问题来源



在实现某具有多级表头格的需求时,发现默认的单元格合并跟UI设计的不同,遂在网上寻找解决方法,于是发现了一个坑

网上的代码:

<template>
<el-table
    ...
    :header-cell-style="setStyle"
    ...
>
    ...
</el-table>
</template>

<script>
export default {
    ...
    method: {
        setStyle({row, column, rowIndex, columnIndex}) {
            if (rowIndex === 0 && columnIndex === 0) {
                column.rowSpan = 2
            }
        }
    }
    ...
}
</script>

此时设置的rowSpan是不生效的

解决思路

因为网上搜到的代码基本都是这么写,故去看了下el-table的源码

table-header.js的render函数中相关源码如下

<th
    /* 此处设置了colSpan, rowSpan */
    colspan={ column.colSpan }
    rowspan={ column.rowSpan }

    on-mousemove={ ($event) => this.handleMouseMove($event, column) }
    on-mouseout={ this.handleMouseOut }
    on-mousedown={ ($event) => this.handleMouseDown($event, column) }
    on-click={ ($event) => this.handleHeaderClick($event, column) }
    on-contextmenu={ ($event) => this.handleHeaderContextMenu($event, column) }

    /* 此处调用getHeaderCellStyle, getHeaderCellClass */
    style={ this.getHeaderCellStyle(rowIndex, cellIndex, columns, column) }
    class={ this.getHeaderCellClass(rowIndex, cellIndex, columns, column) }

    key={ column.id }
>

可以看到在调用getHeaderCellStyle之前就已经赋值了标签的rowSpan,又因为rowSpan的值不是引用类型,故后续的修改不会再影响标签的rowSpan值

原因找到了,如果UI库可以修改的话解决方法比较简单,在源码里将设置rowSpan的代码放到调用getHeaderCellStyle的代码后面即可(CDN引用的UI库目前没想到好的解决方法)

代码:

<th
    on-mousemove={ ($event) => this.handleMouseMove($event, column) }
    on-mouseout={ this.handleMouseOut }
    on-mousedown={ ($event) => this.handleMouseDown($event, column) }
    on-click={ ($event) => this.handleHeaderClick($event, column) }
    on-contextmenu={ ($event) => this.handleHeaderContextMenu($event, column) }

    /* 此处调用getHeaderCellStyle, getHeaderCellClass */
    style={ this.getHeaderCellStyle(rowIndex, cellIndex, columns, column) }
    class={ this.getHeaderCellClass(rowIndex, cellIndex, columns, column) }

    /* 后面设置colSpan, rowSpan */
    colspan={ column.colSpan }
    rowspan={ column.rowSpan }

    key={ column.id }
>

Leave a Reply

Your email address will not be published. Required fields are marked *