如何避免改变传递给 Nuxt 3 组件 prop 对象的原始嵌套对象?

问题描述 投票:0回答:1

我在 Nuxt 3 中通过 props 将数据对象从一个组件传递到另一个组件:

父组件

<template>
  <div>
    <Tests :objParent="objParent" />
  </div>
</template>

<script setup>
const objParent = {title: {en:"title en", fr:"title fr"}}
</script>

子组件

<template>
  <div >
    <h1>objParent : {{ props.objParent.title.en }}</h1>

    <v-text-field label="label" v-model="objChild.title.en" />

    <h1>objChild : {{ objChild.title.en }}</h1>
  </div>
</template>

<script setup>
const props = defineProps(["objParent"]);
const objChild = ref({...props.objParent});
</script>

问题是,如果我改变

objChild
中的嵌套对象,它们仍然会在父组件的原始嵌套对象中发生改变。

在没有嵌套对象的情况下传递对象时,我没有遇到同样的问题 - 例如:

// title can be mutated without mutating the original object
const objParent = {title: "title en"}

我做了一些研究,找到了这个解决方案:

const objChild = ref(JSON.parse(JSON.stringify(props.objParent)));

这是一个有效的解决方案吗?

javascript object vuejs3 nuxt3
1个回答
0
投票

为了扩展 Emil 的评论,由于您的新对象是直接使用原始对象的 props 创建的(通过 spread 运算符),因此每个嵌套对象将继续指向嵌套在原始父对象中的对象。

发生这种情况是因为 JavaScript 中的对象与原始值不同,因为它们是引用类型。当您将一个对象分配给变量时,您为该对象分配了一个引用 - 这意味着如果您继续在其他地方分配相同的对象,它会仍然指向原始对象,并且对于所有它的嵌套对象。

所以:

const x = { hello: 'world' };

const y = { x };

const z = { y };

z.y.x.hello = 'kitty';

// {hello: 'kitty'}
console.log(x);

正如您自己指出的,在 JavaScript 中生成深层副本的一种简单技术是将其序列化/反序列化为 JSON 字符串:

const x = { hello: 'world' };

const y = { x };

const z = JSON.parse(JSON.stringify({ y }));

z.y.x.hello = 'kitty';

// {hello: 'world'}
console.log(x);

// {y: {x: {hello: 'kitty'}}}
console.log(z);

回答你的问题 - 是的,它一种有效、有效且广泛使用的创建深度克隆的方法。但请注意,并非所有内容都可以序列化为 JSON,包括符号键控属性、

BigInt
值和循环引用。请参阅注意事项此处

如果您期望接收的数据已经来自 REST API,则它很可能不包含任何不可序列化的数据。

您可以在此 Stack Overflow 问题中找到其他替代方案(及其注意事项)。

© www.soinside.com 2019 - 2024. All rights reserved.