Reputation: 133
Background: I have an array in data() that gets populated with objects from the backend. If the GET request retrieves 6 objects those 6 objects will update in the array.
Problem: I already understand vm.$set is needed to add properties to an object. But how do add properties to all object in the array?
I want to change:
data() {
return {
expenseButton: [{key:value},{key:value},{key:value}]
};
}
to
data() {
return {
expenseButton: [{key:value, key2:value2},{key:value, key2:value2},{key:value, key2:value2}]
};
}
Failed attempt which logs newValue as a property in the array instead of each object
methods: {
check() {
this.$set(this.expenseButton, "newValue", this.expenseButton.newValue);
console.log(this.expenseButton);
}
},
UPDATE How to target all objects in an array via vm.$set so that all objects has a new property called "newValue"
data() {
return {
expenseButton: [{key1:value1},{key2:value2},{key3:value3}]
};
}
TO
data() {
return {
expenseButton: [{key1:value1,newValue: ''},{key2:value2, newValue: ''},{key3:value3, newValue: ''}]
};
}
Upvotes: 3
Views: 6359
Reputation: 2759
You can use $set
on arrays by passing the index at which you wish to set a new value.
However, since you're adding a new property to each item in the array, you could just map over the array items, add the property and replace the data item altogether which would be far more efficient.
check() {
this.expenseButton = this.expenseButton.map((obj) => {
obj.newValue = ''
return obj
})
}
To retain reactivity, you will need to invoke $set
on each index with the corresponding key-value pair. See @blex's answer for reference.
check() {
this.expenseButton.forEach((_, index) => {
this.$set(this.expenseButton[index], 'newValue', '')
})
}
If the above resolves your question, please accept @blex’s answer as your accepted solution.
Upvotes: 5
Reputation: 25648
You could use this.$set
in a loop:
Vue.component('my-component', {
template: '#my-component',
data() {
return {
expenseButton: [{ key: 0 }, { key: 1 }, { key: 2 }]
};
},
methods: {
check() {
this.expenseButton.forEach((o, i) => {
this.$set(this.expenseButton[i], "key2", i * 2);
});
}
}
});
var vm = new Vue({
el: '#app'
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.21/vue.min.js"></script>
<div id="app">
<my-component></my-component>
</div>
<template id="my-component">
<div>
<ul>
<li v-for="x in expenseButton" :key="x.key">
{{x}}
</li>
</ul>
<button @click="check">Update items</button>
</div>
</template>
Upvotes: 3