Arco Design的Table组件如何动态切换列宽而不触发重渲染?

宇文丽苹 阅读 62

在使用Arco Design的Table组件时,我遇到了一个困扰:当用户拖动列头调整列宽后,表格会整体闪动重渲染。我尝试在columns配置里用了resizable属性,并给Table加了key={columns.join(”)}试图控制,但依然无效。控制台报错”Unexpected re-render”。

我的代码大概是这样写的:


<a-config-provider>
  <a-table :columns="columns" :data="data" resizable>
    <!-- 表格内容 -->
  </a-table>

请问有没有办法让列宽调整只更新DOM样式,而不触发组件整体重新渲染?或者需要如何配置响应式系统?

我来解答 赞 9 收藏
二维码
手机扫码查看
1 条解答
百里欢欢
你这个问题其实是 Arco Design 的 Table 在处理列宽拖动时,内部状态更新触发了 Vue 的响应式系统,导致整个表格组件重新渲染。加 key 来控制也没用,因为 columns 本身是响应式引用,只要它的某个属性变了(比如 width),就会触发依赖收集的更新。

根本原因不是 API 调用方式的问题,而是你用了 resizable 却没关掉内部自动维护列宽的逻辑,它会直接改你传入 columns 的 width 字段,这就踩到 Vue 响应式陷阱了。

解决办法有两个层次:

第一,别让 columns 被响应式劫持。你在定义 columns 的时候,用 markRaw 或者在 setup 里 return 之前把 width 相关字段冻结:

import { markRaw } from 'vue'

const columns = markRaw([
{ title: '姓名', dataIndex: 'name', width: 100 },
{ title: '年龄', dataIndex: 'age', width: 100 }
])


这样 Vue 不会追踪这些字段的变化,拖动列宽时内部虽然还是会改,但不会触发你的组件重渲染。

第二,如果你还想自己控制列宽 DOM 更新而不重渲染,就得接管 onResizeColumn 事件,手动操作 style:

<a-table 
:columns="columns"
:data="data"
@resize-column="handleResize"
resizable
></a-table>


然后在 handleResize 里直接通过 ref 拿到对应的单元格,设置 style.width,避免走响应式流程。

不过最省事的办法还是:升级到 Arco Design 最新版,他们已经在 v2.40+ 里优化了 resizable 的实现,默认只更新样式不触发全量 rerender。你现在的“Unexpected re-render”报错大概率是因为版本太老,内部调试 flag 没关。

先 check 下版本,再配合 markRaw 冻结 columns,基本就能解决问题。别信那些说要 deep clone columns 的方案,性能开销更大还治标不治本。
点赞 3
2026-02-09 08:21