Vue JS V-для V-Bind не является уникальным
Я пытаюсь создать форму, в которой у меня есть список выбора (полученный из API), и пользователь может добавлять элементы в отдельный массив из этого списка. Новый массив также визуализируется через v-for и использует v-модель для редактирования некоторых дополнительных данных.
Например, у меня есть заранее определенный список товаров / услуг, который будет отображаться в блоке выбора. Теперь пользователь может выбрать один из этих продуктов и добавить их в счет. После добавления (переданного в новый массив) пользователь должен иметь возможность внести некоторые дополнительные изменения.
<select class="form-control" v-model="selectedServiceId">
<option v-for="service in services" :value="service._id">{{service.name}}</option>
</select>
<button type="button" class="btn btn-primary" v-on:click="addService">Add</button>
добавить метод обслуживания:
addService() {
for (var i = 0; i < this.services.length; i++) {
if (this.services[i]._id == this.selectedServiceId) {
this.services_goods.push(this.services[i])
break;
}
}
}
И теперь я хочу сделать список, в который я вставил:
<ul>
<li v-for="(item, key) in services_goods">
<span>{{item.name}}</span>
<label for="itemPrice">Price €
<input id="itemPrice" v-model="item.price">
</label>
<label for="itemQty">Quantity
<input type="number" min="1" id="itemQty" v-model="item.quantity">
</label>
<div>
<button type="button" v-on:click="removeService(item._id)">X</button>
</div>
</li>
</ul>
все хорошо, пока я не добавлю один и тот же товар дважды и не попытаюсь изменить цену для одного из них - это изменит цену для обоих.
1 ответ
Причина, по которой он меняет цену для обоих, заключается в том, что они являются одним и тем же объектом. Когда вы вставляете объект в массив, значение в массиве является ссылкой на объект. У вас есть две ссылки на один и тот же объект.
Каждый объект, который вы вставляете в массив, должен быть заново создан, а содержимое скопировано из выбранного элемента.
new Vue({
el: '#app',
data: {
selectedServiceId: null,
services: [{
_id: 1,
price: 1,
quantity: 1,
name: 'First'
},
{
_id: 2,
price: 2,
quantity: 2,
name: 'Second'
}
],
services_goods: []
},
methods: {
addService() {
const foundGood = this.services.find((s) => s._id == this.selectedServiceId);
// Object.assign copies an object's contents
this.services_goods.push(Object.assign({}, foundGood));
}
}
});
<script src="//cdnjs.cloudflare.com/ajax/libs/vue/2.2.6/vue.min.js"></script>
<div id="app">
<select class="form-control" v-model="selectedServiceId">
<option v-for="service in services" :value="service._id">{{service.name}}</option>
</select>
<button type="button" class="btn btn-primary" v-on:click="addService">Add</button>
<ul>
<li v-for="(item, key) in services_goods">
<span>{{item.name}}</span>
<label for="itemPrice">Price €
<input id="itemPrice" v-model="item.price">
</label>
<label for="itemQty">Quantity
<input type="number" min="1" id="itemQty" v-model="item.quantity">
</label>
<div>
<button type="button" v-on:click="removeService(item._id)">X</button>
</div>
</li>
</ul>
</div>