Vue3如何避免修改props对象?每次调用函数需重置变量初始值
Vue中修改props对象导致原数据累加的问题解决
我的代码
const props = defineProps({ a: Object }) function calcs() { var b = props.a; b.push({ xxx: yyy }); }
props.a初始值为{x: 'y'}
需求与问题
我希望每次调用calcs函数时,执行b.push前b的值都是{x: 'y'},但目前b会持续累加xxx:yyy,且props.a也被修改了。尝试过ref(props.a)、reactive(props.a)都无效。
调用输出情况
第一次调用calcs的输出:
props.a={x: 'y'} b={x: 'y',xxx: 'yyy'}
第二次调用输出:
props.a={x: 'y',xxx: 'yyy'} b={x: 'y',xxx: 'yyy',xxx: 'yyy'}
第三次调用输出:
props.a={x: 'y',xxx: 'yyy',xxx: 'yyy'} b={x: 'y',xxx: 'yyy',xxx: 'yyy',xxx: 'yyy'}
原因分析
对象是引用类型,var b = props.a并没有创建新对象,只是让变量b指向了props.a在内存中的同一个地址。所以你对b做的任何修改,都会直接作用到原props.a上。而ref或reactive包装原对象时,依然是基于原引用,不会生成新的独立对象,所以没用。
解决方法
每次调用calcs时,先对props.a做深拷贝,生成一个完全独立的新对象,再修改这个新对象。根据对象层级不同,有几种方式:
1. 浅拷贝(适用于单层对象)
如果props.a只有一层属性,用扩展运算符或者Object.assign:
function calcs() { // 扩展运算符浅拷贝 var b = {...props.a}; b.xxx = 'yyy'; }
2. 深拷贝(适用于多层嵌套对象)
如果props.a是多层嵌套的对象,用浏览器原生的structuredClone:
function calcs() { var b = structuredClone(props.a); b.xxx = 'yyy'; }
如果项目里引入了lodash,也可以用_.cloneDeep(props.a)实现深拷贝。
针对数组的修正代码(若props.a实际为数组)
如果你的props.a是数组(原代码用了push方法),深拷贝后再操作:
const props = defineProps({ a: Array }) function calcs() { var b = structuredClone(props.a); b.push({xxx: 'yyy'}); // 此时每次b的初始值都是props.a的原始值,不会修改原props }
内容的提问来源于stack exchange,提问作者Bob M
相关产品推荐
相关产品推荐

