VueCLI循环始终返回最后值,如何基于data生成目标variants数组?
解决Vue循环中基于现有对象生成独立新对象的问题
你遇到的问题本质是对象的引用传递特性在搞鬼!因为this.p是一个对象,当你直接把它赋值给raw时,raw并没有变成一个新对象,只是和this.p指向了内存里的同一个地址。所以循环里每次修改raw.option_1,其实都是在修改原来的this.p,最后variants数组里的所有元素都是同一个对象的引用,自然最终显示的都是循环最后一次赋值的结果。
下面给你几种靠谱的解决方案,都能实现你想要的variants结构:
方案1:用扩展运算符创建新对象(最简洁)
扩展运算符...可以快速浅拷贝原对象的所有属性,然后我们再覆盖option_1的值,这样每次循环都会生成一个全新的对象:
methods: { add() { this.options[0].values.forEach(value => { const newVariant = { ...this.p, option_1: value }; this.variants.push(newVariant); }); } }
方案2:使用Object.assign方法
Object.assign同样可以创建新对象,它会把第一个参数(空对象)和后续对象的属性合并,最终返回一个新对象:
methods: { add() { for(let i = 0; i < this.options[0].values.length; i++) { const currentValue = this.options[0].values[i]; const newVariant = Object.assign({}, this.p, { option_1: currentValue }); this.variants.push(newVariant); } } }
方案3:深拷贝(适用于复杂嵌套对象)
如果你的this.p有嵌套的对象结构,浅拷贝就不够用了,这时候可以用JSON.parse(JSON.stringify())做深拷贝(注意:这种方法不适合包含函数、Symbol等特殊类型的对象):
methods: { add() { this.options[0].values.forEach(value => { // 深拷贝生成新对象 const raw = JSON.parse(JSON.stringify(this.p)); raw.option_1 = value; this.variants.push(raw); }); } }
顺便提一下你原来的自执行函数代码的问题:除了引用传递的问题,自执行函数里的this默认并不是Vue实例(非严格模式下指向window),所以this.options其实会报错,这也是为什么你原来的逻辑跑不通的原因之一。
只要保证每次循环都生成独立的新对象,而不是复用this.p的引用,就能得到你想要的variants数组啦!
内容的提问来源于stack exchange,提问作者SwadhIn
相关产品推荐
相关产品推荐

