Version: Ant Design 3.26.7
Issue: Ant-design Table组件当滚动列的行高变化时,固定列的行高不会同步变化,或固定列变化滚动列不变,造成布局破坏。

本来以为是文档没有看仔细,想寻求官方的配置方式来解决该问题。既然官方仍在 处理中 ,在这里给出自己的解决方案,希望能够帮到其他同学。

首先,先解释下 Table组件“固定头和列” 的实现原理。我们所看到的一个Table组件,其本质是有三个Table元素组成,只不过被用特殊样式的容器div(Wrapper div)包裹起来。如下所示

<div class="ant-table-content">
  <div class="ant-table-scroll">...</div>
  <div class="ant-table-fixed-left">...</div>
  <div class="ant-table-fixed-right">...</div>
</div>

通过类名我们可以很直观的了解,一个表被固定在左,一个固定在右,一个位于中间用于滚动。

在创建表的时候,我们通过Columnfixed: true|left|right|false 属性来决定该列属于哪个容器,或者说 “指定这三个容器各自包含哪些列”。准确来说,应该是 指定left,right这两个固定容器各自包含哪些列,因为scroll容器包含了全部的列 ,这也是实现这种推拉效果的核心。

需要注意的是,ant-table-fixed-leftant-table-fixed-right,由于被固定在左右,所以不能左右滚动,所以它们的包装容器,被设置为

<div style=“max-height: ${y}; overflow-y: scroll;”> </div>

仅实现上下滚动。

ant-table-scroll需要同时满足左右上下滚动,所以被设置为

<div style=“max-height: ${y}; overflow: scroll;”> </div>

其中这里的y,等于你所设置的Table组件的scroll.y属性。(个人见解,如果有误请指出,先谢过)

先看正常状态
在这里插入图片描述
根据产生原因可分为两类

  • 滚动列发生变化,固定列不变,布局被破坏。
    在这里插入图片描述
  • 固定列发生变化,滚动列和另一个固定列不变,布局被破坏。
    在这里插入图片描述

这里我们以“右固定列发生变化”为例,进行问题解决,通过同样的方式你也可以很容易得出其他情况的解决方式。

先给出表的代码

<Table id={tableId} rowKey={(t, index) => {
                        /**指定key,为了在行tr高改变的时候,获取其他容器中对应的行*/
                        t.key = `${t.name}-${index}`; return t.key;
                    components={components}
                    rowClassName={() => 'editable-row'}
                    defaultExpandAllRows
                    scroll={{ y: 'max-content', x: 1300 }}
                    pagination={false} columns={columns} dataSource={dataSource} />

右固定列发生变化,采用滚动列和左固定列伸缩恢复布局。

在组件更新(componentDidUpdate)时,获取右固定容器发生变化的行tr的真实高度(height),对滚动容器和左固定容器的对应行trstyle.height 进行相应改变。

    const [rowKeyObject, setRowKeyObject] = useState({});
    const onUp = (rowKey) => setRowKeyObject({ rowKey });
    const didUpdateRef = useRef(false);
    useEffect(() => {
        if (!didUpdateRef.current) {
            didUpdateRef.current = true;
            return;
        const { rowKey } = rowKeyObject
        if (!rowKey)
            return;
        const scrollDiv = document.querySelector(`#${tableId} .ant-table-scroll > .ant-table-body`);
        const leftFixedDiv = document.querySelector(`#${tableId} .ant-table-fixed-left .ant-table-body-inner`);
        const rightFixedDiv = document.querySelector(`#${tableId} .ant-table-fixed-right .ant-table-body-inner`);
        const cssSelector = `table.ant-table-fixed tr[data-row-key='${rowKey}']`;
        const rightFixedTr = rightFixedDiv.querySelector(cssSelector);
        const leftFixedTr = leftFixedDiv.querySelector(cssSelector);
        const scrollTr = scrollDiv.querySelector(cssSelector);
        const theoryTrHeight = getComputedStyle(rightFixedTr).height;
        scrollTr.style.height = theoryTrHeight;
        leftFixedTr.style.height = theoryTrHeight;
        console.log(theoryTrHeight);
    });
  • useEffect()在组件挂载(componentDidMount)和更新(componentDidUpdate)时都会被执行,显然在挂载时我们不需要执行函数中的复杂逻辑,这里使用易变对象ref(mutable ref)来优化,ref.current做状态标记,挂载时不再执行复杂逻辑。
  • 这里id={tableId},是针对多表同时存在时使用的,tableId作唯一标识,如果你的Document中只有一个Table组件存在,那么你可以忽略该属性。
  • 为了获取变化的行tr,我们需要指定Table组件的rowKey属性(rowKey对应了tr的data-row-key属性),同时需要在tr高度发生变化时将rowKey值传递给useEffect(),所以你需要保证你的EditableCell组件能够准确的拿到相应rowKey值。在这里,我将它绑定到了record.key
  • 设置rowKey状态时,没有直接使用
     const [rowKey, setRowKey] = useState(null);
    
    而是使用
     const [rowKeyObject, setRowKeyObject] = useState(null);
    
    原因是——如果某行tr高度持续变化,那么传递到setRowKey(rowKey)rowKey将是相等(===)的值,React认为State未发生变化,组件不会更新,useEffect()不会被执行。而setRowKeyObject({rowKey}),每次会创建一个新的State对象,其引用Reference,是不相等的(===),组件会更新,useEffect()会执行。
  • 行tr高度但凡发生变化,你都需要促使组件更新,useEffect()执行。那么你需要在EditableCell组件中设置相应的监听函数,例如onKeyUponMouseUponMouseOveronMouseEnter等等。例如,
    return (<td {...restProps} onKeyUp={() => onUp(record.key)} onMouseUp={() => onUp(record.key)} >
                {editable ? this.renderCell() : children}
            </td>);
    

    如果有错误的地方,请指出,先行谢过。

    修订:Ant Design v4已经发布,直接升级到v4,问题就全解决了《从 v3 到 v4》

    需求:在原本表格基础上设置左右固定。 现有情况:个别表格不带勾选框,个别表格带勾选框。 问题描述:前者直接给加上fixed即可,后者加上fixed会出现可移动被左侧固定遮挡部分的情况。 给表格设置固定后,实际上就从一个表变为了多个表。原始的表格为一个表,含有最初的所有,左侧固定为一个表,右侧固定为一个表。检查元素发现,原始表格勾选框的宽度较左侧固定表中的勾选框宽度更短,导致移动向前缩进被左侧固定在上方遮挡。 查阅官方文档,找到选择功能的配置rowSelection,其中自定义.
    1.1 node_modules\ant-design-vue\es\vc-table\src\Table if(window.navigator.userAgent.match(/Trident\/7\./)&&scroll.y) 改为 if(scroll.y) 解决滚动同步问题 1.2 node_modules\ant-design-vue\es\vc-table\src\BaseTable 注释 //this.store.currentHoverKey...
    设置 y 之后,侧边栏出现白边:https://github.com/react-component/table/issues/998 设置scroll y之后,x为max-content失效:https://github.com/ant-design/ant-design/issues/29283 设置吸顶的候出现双滚动条:
    项目中使用 AntDesign 的表格组件固定后,发现导致行的高度一致; 尝试了给tr固定高度,表面上可行,但如果有一行的内容长度过多,仍会导致层次不齐; ::v-deep .ant-table .ant-table-tbody tr { height: 50px !important; 最后发现是自己的问题,哈哈哈哈 <a-table :data-source="tableDataList" :loadi
    el-table 使用fixed 固定 但是固定不会随着Y轴滑动 el-table-column prop=“date” label=“日期” 今天工作中遇到一个问题,在用el-table固定功能的候发现我固定的那一不会随着未固定的表格一起沿Y轴滚动 ,像下面这种,右边动,左边不动 在网上找了一圈,发现大部分是固定盖住了横向滚动轴的解决方法,和随Y轴滚动并没有什么关系,所以,经过我一番仔细研究,略有成就,分享出来,大家互相交流。 解决BUG: 找到el-table下面的 el-table_
    如图所示,在固定头和列后出现了几个问题,查看原因后得知是表格下部出现滚动条导致的,所以我把左右固定高度减去滚动条的高度就可以解决这个问题 mounted () { // this.h = document.querySelector('.ptp-layout-main').offsetHeight - 45 const _this = this var tableBodyInnerNodeList = document.querySelectorAll('.ant-table-body-.
    文章目录使用 ant-design 官网上的 Table 固定样式代码实现效果展示查找问题解决方法 使用 ant-design 官网上的 Table 固定样式 链接: https://antdv.com/components/table-cn/#components-table-demo-fixed-columns 由于我的项目要实现左边第一例为左固定,右边最后一操作为右固定,按照官网上的操作一顿噼噼啪啪操作完后,效果图和代码如下: 可以看到,我的 columns 设置宽度的
    对于 Element UI 的 Table 组件,合并行高变高的问题可以通过自定义单元格的样式来解决。以下是一种可能的解决方案: 1. 在需要合并的单元格中,使用自定义的样式来控制行高。可以通过设置 `line-height` 属性来调整行高,将其设置为合适的值。 2. 在 Table 组件中,可以使用 `cell-style` 属性来设置单元格的样式。通过这个属性,你可以为每个单元格设置自定义的样式。 下面是一个示例代码,展示如何使用自定义样式来解决合并行高变高的问题: ```html <template> <el-table :data="tableData"> <el-table-column prop="name" label="姓名"></el-table-column> <el-table-column prop="age" label="年龄"></el-table-column> <el-table-column prop="address" label="地址"></el-table-column> <el-table-column prop="mergedCell" label="合并" :formatter="mergeCellFormatter"></el-table-column> </el-table> </template> <script> export default { data() { return { tableData: [ { name: '张三', age: 18, address: '北京', mergedCell: '合并内容' }, { name: '李四', age: 20, address: '上海', mergedCell: '' }, { name: '王五', age: 22, address: '广州', mergedCell: '' }, methods: { mergeCellFormatter(row, column, cellValue, index) { // 判断当前单元格是否需要合并 if (index === 0) { return { rowspan: 3, // 合并的行数 style: 'line-height: 60px;', // 设置行高 content: cellValue, // 单元格内容 } else { return { rowspan: 0, // 不合并 content: '', // 空内容 </script> 在上述示例中,我们通过 `mergeCellFormatter` 方法来控制合并的样式和内容。通过设置 `rowspan` 属性来指定合并的行数,同设置 `style` 属性来调整行高。 注意:上述示例仅为示意,实际使用需要根据你的具体需求进行调整和优化。
    root cause org.apache.ibatis.ognl.OgnlException: source is null for getProperty(null, "XXX") 45744