Vue中使用structuredClone()克隆ref变量值报错如何解决
问题原因
Vue 3 默认创建的ref是深层响应式对象,访问.value拿到的值不是普通JavaScript对象,而是Vue内部包裹生成的Proxy代理实例。structuredClone()本身不支持克隆Proxy类型的对象,因此会抛出「无法克隆」的错误。
普通场景下直接定义的对象没有经过Proxy代理,属于structuredClone支持的可克隆类型,因此可以正常运行。
修复方案
方案1:使用toRaw获取原始对象后克隆(推荐)
Vue提供了toRaw工具函数,可以拿到响应式Proxy对象对应的原始普通对象,原始对象没有响应式绑定,完全符合structuredClone的入参要求,是最通用的修复方式。
修复对象类型ref的示例代码:
import { ref, toRaw } from "vue"; const a = ref({ foo: { bar: "+" } }); // 先取出原始普通对象,再执行深拷贝 const b = structuredClone(toRaw(a.value));
修复ref数组遍历克隆的示例代码:
import { ref, toRaw } from "vue"; const a = ref([{ foo: { bar: "+" } }]); for (const item of a.value) { // 数组内的元素同样是Proxy代理对象,需要先转原始值再克隆 const c = structuredClone(toRaw(item)); }
注意:
toRaw返回的原始对象和响应式代理引用的是同一份底层数据,不要直接修改toRaw返回的对象,否则会绕开Vue的响应式更新机制,仅将它作为深拷贝的数据源是完全安全的。
方案2:场景适配时使用shallowRef替代ref
如果你当前的业务场景不需要对ref内的对象做深层响应式追踪,可以改用shallowRef创建响应式变量。shallowRef不会对内部值做深层Proxy代理,.value本身就是你传入的原始对象,可以直接传入structuredClone执行克隆:
import { shallowRef } from "vue"; const a = shallowRef({ foo: { bar: "+" } }); // 直接克隆即可,不会报错 const b = structuredClone(a.value);
注意:
shallowRef只有在整体替换.value值时才会触发视图更新,直接修改对象深层属性、数组内部元素不会触发响应式更新,需要根据业务需求选择,不要为了适配深拷贝盲目替换。
内容的提问来源于stack exchange,提问作者user19025657
相关产品推荐
相关产品推荐

