在Vue.js中,为了向虚拟DOM中已有的对象添加属性/数组项,you have to use the $set function。
这是错误的方式:
对象: this.myObject.newProperty = "value";
数组: this.myArray[3] = object;
这是正确的方法:
对象: this.$set(this.myObject, "newProperty", "value");
数组: this.$set(this.myArray, 3, object);
我的问题是您如何设置数组中所有对象的属性?
这是错误的方式:
for (var i = 0; i < this.myArray.length; i++) {
this.myArray[i].newProperty = "value";
}
那么,我使用$ set进行此操作的方法是什么?
答案 0 :(得分:1)
您继续使用索引循环执行this.$set(this.myArray, 3, object);
。
修改对象后,类似的东西。
var newObject = Object.assign({}, this.myArray[i], {newProperty: 'value'} ); // Immutable object created
this.$set(this.myArray, i, newObject);
这将是低效的,因为它将在每次迭代时调用$set
。
因此您可以在数组上做一个映射,然后从内部返回一个新的Object。
const newArray = myArray.map(object => {
return Object.assign({}, object, {newProperty: 'value'} );
//or by ES6 spread operator
return {...object, newProperty: 'value'};
});
然后将您的数组设置为重新渲染Vuejs。
希望,这将给出想法。尽管上下文可能会根据您的实现方式而有所不同!
答案 1 :(得分:1)
您的作品经过一些调整的代码:
new Vue({
el: "#app",
data: {
todos: [{
text: "Learn JavaScript",
done: false
},
{
text: "Learn Vue",
done: false
},
{
text: "Play around in JSFiddle",
done: true
},
{
text: "Build something awesome",
done: true
}
]
},
methods: {
toggle: function(todo) {
todo.done = !todo.done
},
changeProperty1() {
const val = 'A'
// this is your code a bit modified
// defining length (and using it in the comparison) is a
// bit of optimization, not required
for (var i = 0, length = this.todos.length; i < length; i++) {
this.$set(this.todos[i], 'property1', val);
}
},
changeProperty1Again() {
for (todo of this.todos) {
if (todo.property1) {
todo.property1 = 'B'
}
}
}
},
created() {
}
})
body {
background: #20262E;
padding: 20px;
font-family: Helvetica;
}
#app {
background: #fff;
border-radius: 4px;
padding: 20px;
transition: all 0.2s;
}
li {
margin: 8px 0;
}
h2 {
font-weight: bold;
margin-bottom: 15px;
}
del {
color: rgba(0, 0, 0, 0.3);
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<h2>Todos:</h2>
<ol>
<li v-for="todo in todos">
<label>
<input type="checkbox"
v-on:change="toggle(todo)"
v-bind:checked="todo.done">
<del v-if="todo.done">
{{ todo.text }}
</del>
<span v-else>
{{ todo.text }}
</span>
<span>
{{ todo.property1 }}
</span>
</label>
</li>
</ol>
<button @click="changeProperty1">Click this first</button>
<button @click="changeProperty1Again">Click this second</button>
</div>
很抱歉,冗长的代码段是我从JSFiddle复制过来的:)
答案 2 :(得分:1)
您只是想向数组中的对象添加新属性。不通过其索引为数组设置新值。您可以执行以下操作:
new Vue({
el: '#demo',
data: {
myArray: [
{id: 1},
{id: 2},
{id: 3},
{id: 4},
{id: 5}
]
},
methods: {
addProperties() {
for (var i = 0; i < this.myArray.length; i++) {
this.$set(this.myArray[i], 'newProperty', 5 - i)
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="demo">
<div v-for="item in myArray" :key="item.id">
<span>{{item.id}}: </span>
<span v-if="item.newProperty">{{item.newProperty}}</span>
</div>
<button @click="addProperties">Add Properties</button>
</div>
答案 3 :(得分:0)
并不是真正的问题-只是普通的JS:
arr.map(obj => { return {...obj, newProperty: "sameValueAsOthers"}});