I want to make use of the structuredClone() function inside my Vue app. I want to use this to create a deep clone ( instead of using workarounds like stringify and parse or external libraries ). Inside my setup function the following code is fine
const a = {
foo: {
bar: " "
}
};
const b = structuredClone(a);
console.log(b);
But it is not possible for me to use it on values of ref variables. This example code
import { ref } from "vue";
const a = ref({ foo: { bar: " " } });
const b = structuredClone(a.value);
throws the error
Uncaught DOMException: Failed to execute 'structuredClone' on 'Window': # could not be cloned.
The same goes for items from ref arrays
import { ref } from "vue";
const a = ref([{ foo: { bar: " " } }]);
for (const b of a.value) {
const c = structuredClone(b);
}
How can this be fixed?
CodePudding user response:
The error means that structuredClone
was executed on Proxy
instance, which cannot be cloned. In order to allow this, it should be used on raw object that a proxy wraps:
const b = structuredClone(toRaw(a.value));
Notice that toRaw
is used on a.value
because both a
and a.value
are reactive objects, and toRaw
works shallowly and needs to be applied to the innermost object.
Since ref
and reactive
allow to compose reactive objects, toRaw
still may not work for them due to how it works:
ref({ foo: { bar: barRef } })
This would require to recursively use toRaw
on reactive objects before using structuredClone
. At this point this doesn't make it easier than cloning the objects manually, unless more exotic objects like Set
, Map
, etc are in use.