Vue中向数组添加对象后如何切断与原对象的关联
问题:Vue中数组内对象与原输入对象始终关联,如何切断引用?
我为博客制作了一个表单,blog是包含多个content对象的ref对象。即便contentItem不是ref类型,将其推入blog的content数组后,数组中的对象仍与原contentItem保持关联。尝试过readonly、直接赋值给新对象都没用,数组内的对象和原对象始终是同一个。
对应的Vue组件代码:
<script setup lang="ts"> const blog = ref({ link: 'Link', category: 'category', title: 'title', image: 'Image', body: 'Body', content: [] as any[] }) let contentItem = { parent: 'parent', title: 'title', image: 'Image', code: 'Code', body: 'Body', } // Add Content Item function addContent(content: any) { const item = content blog.value.content.push(item) } </script> <template> <div class="flex p-8 text-slate-600 w-full flex-col gap-4 rounded"> <h4 class="font-bold text-red-50">Blog Content</h4> <input type="text" v-model="contentItem.parent"> <input type="text" v-model="contentItem.title"> <input type="text" v-model="contentItem.image"> <textarea class="w-full h-[200px]" type="text" v-model="contentItem.code"> {{ contentItem.code }} </textarea> <textarea class="w-full h-[200px]" type="text" v-model="contentItem.body"> {{ contentItem.body }} </textarea> <button class="p-4 w-1/2 bg-slate-50" type="button" @click="addContent(contentItem)">Add Content</button> </div> </template>
解决方法
核心是创建原对象的副本,JavaScript中对象属于引用类型,直接赋值仅传递内存地址,导致数组内对象与原对象指向同一内存空间。
1. 浅拷贝对象(适用于无嵌套对象的场景)
在addContent函数中,通过展开运算符或Object.assign创建原对象的浅拷贝,再推入数组:
修改后的addContent函数:
function addContent(content: any) { // 用展开运算符生成新对象副本 const item = {...content} blog.value.content.push(item) }
或使用Object.assign实现:
function addContent(content: any) { const item = Object.assign({}, content) blog.value.content.push(item) }
2. 可选:添加完成后重置输入对象
为避免用户继续修改contentItem时产生混淆,建议添加完成后重置输入对象:
function addContent(content: any) { const item = {...content} blog.value.content.push(item) // 重置输入对象为初始状态 contentItem = { parent: 'parent', title: 'title', image: 'Image', code: 'Code', body: 'Body', } }
3. 处理嵌套对象(深层拷贝)
如果contentItem包含嵌套对象,浅拷贝无法切断深层引用,可使用JSON.parse(JSON.stringify(content))实现深拷贝:
function addContent(content: any) { const item = JSON.parse(JSON.stringify(content)) blog.value.content.push(item) }
注意:该方法不适用于包含函数、Symbol、循环引用的对象。
内容的提问来源于stack exchange,提问作者Tyler Benton
相关产品推荐
相关产品推荐

