vuejs for loop 总是返回最后一个值



在 vuecli 中,我有这样的数据

data() {
return {
options: [{
values: ['a', 'b', 'c']
}],
variants: [],
p: {            
option_1: null 
}
}
}

当我在一个看起来像这样的方法中运行一个循环时

methods: {
add() {
for(let i = 0; i < this.options[0].values.length; i++) {
(function(i, p){
var raw = p;
raw.option_1 = this.options[0].values[i]; 
this.variants.push(raw); 
})(i, this.p);
} 
}
}

我尝试了很多方法,但只有当我像var raw = {option_1: null}一样在循环中设置raw的值时,我才能成功。

但这不是我想要的。我想从data中获取值并在循环中使用它来生成

variants: [{ option_1: 'a' }, { option_1: 'b' }, { option_1: 'c' }]

我怎样才能做到这一点?

你需要一个raw的副本,因为variants中的raw只是一个指向同一对象的引用。这就是为什么你得到了三个相同的值。

add() {
let self = this
for (let i = 0; i < self.options[0].values.length; i++) {
(function (i, p) {
var raw = p;
raw.option_1 = self.options[0].values[i];
self.variants.push(JSON.parse(JSON.stringify(raw)));
})(i, self.p);
}
// this.options[0].values.forEach(v => {
//     this.variants.push({ option_1: v })
// })
}

注释中的代码是一种更优雅的方式。

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.13/vue.min.js"></script>
<div id="app">
<mytag></mytag>
</div>
<script>
let mytag = Vue.component("mytag", {
template: `<div><button @click="add">add</button><p>this.variants:{{this.variants}}</p></div>`,
data() {
return {
options: [{
values: ["a", "b", "c"]
}],
variants: [],
p: {
option_1: null
}
};
},
methods: {
add() {
let self = this
for (let i = 0; i < self.options[0].values.length; i++) {
(function(i, p) {
var raw = p;
raw.option_1 = self.options[0].values[i];
self.variants.push(Object.assign({}, raw));
//self.variants.push(JSON.parse(JSON.stringify(raw)));
})(i, self.p);
}
// this.options[0].values.forEach(v => {
//     this.variants.push({ option_1: v })
// })
}
}
});
new Vue({
el: '#app',
components: {
mytag
}
})
</script>

最后,你最好学习如何提问!

如果您希望最终结果如下所示

variants: [{
option_1: 'a'
}, {
option_1: 'b'
}, {
option_1: 'c'
}]

如果每个条目都按p模板化,并为每个values条目设置option_1,则可以使用

this.variants = this.options[0].values.map(option_1 => ({...this.p, option_1 }))

这会将映射到具有键option_1和每个项的值的对象数组。


如果要在每次调用add()时添加 3 个对象,请将其更改为使用Array.prototype.concat()

this.variants = this.variants.concat(
this.options[0].values.map(option_1 => ({...this.p, option_1 })))

最新更新