VueJS中Object.assign复制对象失效,修改克隆对象影响原对象
解决Vue中克隆对象后原对象同步修改的问题
我来帮你拆解这个问题——你遇到的是浅拷贝与深拷贝的经典陷阱!
为什么Object.assign({}, item)没用?
Object.assign做的是浅拷贝:它只会复制对象的第一层属性,如果你的item里包含嵌套的对象、数组(比如你提到的this.roteiroCompleto[0]有深层结构),这些嵌套的子对象/数组其实还是引用着原对象的内存地址。所以当你修改this.editItem里的嵌套内容时,本质上还是在修改原对象的引用,自然会同步影响this.roteiroCompleto[0]。
你试过的手动复制键值、.slice()、.map(a=>a)也都是浅拷贝逻辑:
- 手动复制如果只处理了第一层键值,嵌套部分还是引用;
.slice()和.map()仅对数组有效,而且也只是浅拷贝数组里的元素对象,嵌套结构依然共享引用。
为什么另一个组件相同策略可行?
大概率是另一个组件里的item是扁平结构(没有嵌套的对象/数组),浅拷贝已经能完全切断和原对象的引用关系,所以修改克隆对象不会影响原对象。
可行的解决方案
根据你的场景,推荐几种深拷贝的方法:
1. JSON序列化反序列化(简单通用)
如果你的对象里没有函数、Symbol、Date这类特殊类型,这个方法最方便:
this.editItem = JSON.parse(JSON.stringify(item))
原理是把对象转成JSON字符串(彻底脱离内存引用),再转成新对象,完美切断所有层级的引用。
2. 浏览器原生API structuredClone(Vue3推荐)
现代浏览器支持的原生深拷贝API,支持循环引用、Date、Map等特殊类型,比JSON方法更强大:
this.editItem = structuredClone(item)
3. Vue内置工具(Vue2适用)
Vue2内置了深拷贝工具,可以直接用:
this.editItem = Vue.util.extend({}, item)
4. lodash的cloneDeep(复杂场景)
如果你的对象包含复杂类型(比如函数、自定义类实例),可以用lodash的深拷贝方法:
// 先安装lodash:npm i lodash import _ from 'lodash' this.editItem = _.cloneDeep(item)
总结
核心就是判断对象是否有嵌套结构:扁平结构用浅拷贝,嵌套结构必须用深拷贝才能彻底切断引用。
内容的提问来源于stack exchange,提问作者extraxt
相关产品推荐
相关产品推荐

