浅拷贝克隆表格列配置是为了避免多个表格实例或动态列修改时因共享引用(如render函数、slots对象)导致相互影响;直接赋值或展开语法仅复制数组,内部引用属性仍共享,修改newcols[0].slots.default等会污染原配置。

在表格列配置中使用浅拷贝克隆对象,是为了避免多个表格实例或动态列修改时相互影响——因为列配置(如 columns 数组)通常包含引用类型字段(如 render 函数、filters 对象、scopedSlots 等),直接赋值会导致共享引用。
为什么不能直接用赋值或展开语法?
直接写 const newCols = columns; 或 const newCols = [...columns]; 只是浅拷贝数组本身,但每个列对象内部的属性(尤其是函数、嵌套对象)仍是原引用。一旦你修改了 newCols[0].title 没问题,但若执行 newCols[0].slots.default = ...,原配置也可能被改掉(如果 slots 是同一对象引用)。
推荐的浅拷贝方式(仅限列配置场景)
对表格列配置这类结构相对扁平、且不深含多层嵌套对象的场景,以下方法够用又安全:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
-
数组 + 对象逐层展开:适用于列对象属性基本是字符串、布尔、函数、一级对象(如
slots、customRender)的情况const newColumns = columns.map(col => ({ ...col, slots: { ...col.slots }, filters: { ...col.filters } }));
注意:只展开你明确知道需要隔离的一级引用属性,函数本身无需拷贝(函数是引用,但一般不该改函数体)。 -
Object.assign + 显式复制关键引用字段:
const newColumns = columns.map(col =><br> Object.assign({}, col, {<br> slots: { ...col.slots },<br> filters: { ...col.filters },<br> scopedSlots: { ...col.scopedSlots }<br> })); -
JSON.parse(JSON.stringify()) 要慎用:它会丢弃函数、undefined、Symbol、Date、RegExp 等,列配置里若有
render(h) {...}就直接失效,不推荐。
实际应用小技巧
如果你的列配置中大量使用了 scopedSlots 或自定义 customRender,建议把它们抽成独立函数变量,而非内联对象——这样即使引用共享也无副作用;真正需要隔离的是可变数据,比如 filters.value、sorter.multiple 这类运行时状态字段。
例如:const baseColumns = [ { title: '姓名', dataIndex: 'name', scopedSlots: { customRender: 'nameSlot' } } ];const table1Columns = baseColumns.map(c => ({ ...c, scopedSlots: { ...c.scopedSlots } }));const table2Columns = baseColumns.map(c => ({ ...c, scopedSlots: { ...c.scopedSlots } }));
这样两个表格的 scopedSlots 对象互不干扰,但都指向同一个 slot 名(安全)。
Vue / Ant Design Vue / Element Plus 场景注意
在这些框架中,列配置常作为 props 传入表格组件。如果你在 computed 或 setup() 中返回列配置,务必每次返回新数组+新对象,否则响应式更新可能失效或引发意外复用。不要在 data 或 ref 中缓存未拷贝的列数组并反复复用。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










