Я столкнулся с проблемой. Я пытаюсь закодировать корзину покупок.
У меня есть 4 компонента:
- LivingRoom.vue (где отображаются все товары из Product)
- Product.vue (шаблон с названием, описанием и ценой для каждого товара),
- ProductDetails.vue (подробности для каждого продукта)
- ShoppingCart.vue.
У каждого товара в ProductDetails есть кнопка с функцией addToCart
, которая принимает в качестве аргумента опору. Каждый раз, когда я пытаюсь добавить новый продукт (объект) в массив, предыдущий, вероятно, заменяется новым. Я делаю глубокую копию каждого объекта, используя Vue.util.extend
, так что свойство количества обновляется. И это прекрасно работает. Но когда я пытаюсь добавить другой элемент в массив корзины, предыдущий элемент исчезает, а новый отображается. Я использую EventBus, и корзина отправляется из компонента ProductDetails в компонент ShoppingCart.
Я помог себе, используя этот код: https://codepen.io/anon/pen/BEEwqd
Там все отлично работает.
Я получаю данные из локальной системы (static / products.json).
Я пытался импортировать проект из github в codesandbox, чтобы вам было проще, но почему-то он работает не так, как ожидалось, поэтому я вставляю ссылку на репо:
https://github.com/rafalpyska/weeklywebdevchallange10
LivingRoom.vue
<template lang="html">
<div class="container">
<transition-group tag="section" class="products" name="list">
<Product
v-for="item in dataToDisplay"
:item="item"
:key="item.id"
@click.native="handleProductDetails(item)"
/>
</transition-group>
</main>
<ProductDetails
v-if="isProductDetailsOpen"
:item="itemDetails"
:data="data"
/>
</template>
<script>
const API = '/static/products.json';
export default {
name: 'LivingRoom',
data() {
return {
status: true,
data: [],
dataToDisplay: [],
itemDetails: null,
}
},
components: {
Product,
ProductDetails
},
created() {
axios.get(API)
.then((response) => {
this.data = response.data[0].category[0];
for (let key in this.data) {
if (!this.data.hasOwnProperty(key)) continue;
this.dataToDisplay = this.data[key];
}
this.status = false;
})
},
methods: {
handleProductDetails(item) {
this.isProductDetailsOpen = true;
this.itemDetails = item;
}
}
Product.vue
<template lang="html">
<div>
<p>class="products__name">{{ name }}</p>
<p class="products__description">{{ description)</p>
<p class="products__price">${{ price }}</p>
</div>
</template>
<script>
export default {
name: "Product",
props: {
item: {
required: true
}
},
data() {
return {
name: this.item.title,
description: this.item.description,
price: this.item.price,
}
}
};
</script>
ProductDetails.vue
<template lang="html">
<section class="product-details">
<h2 class="product__name">{{ name }}</h2>
<label for="quantity">Quantity</label>
<input class="input__quantity" id="quantity" max="10" min="1" name="quantity" type="number"
v-model.number="item.quantity">
<button @click="addToCart(item)" class="btn">Add to cart</button>
</section>
</template>
<script>
import Vue from 'vue'
import {EventBus} from "@/event-bus.js";
export default {
name: "ProductDetails",
props: {
item: {
type: Object,
required: true
},
data: {
type: Object,
required: true
}
},
data() {
return {
cart: [],
name: this.item.title,
id: this.item.id,
quantity: this.item.quantity
}
},
methods: {
addToCart(productToAdd) {
let found = false;
this.cart.forEach((item) => {
if (item.id === productToAdd.id) {
found = true;
item.quantity += productToAdd.quantity;
}
});
if (found === false) {
this.cart.push(Vue.util.extend({}, productToAdd));
}
productToAdd.quantity = 1;
EventBus.$emit('update-cart', this.cart);
}
}
};
</script>
ShoppingCart.vue
<template lang="html">
<div class="cart" v-for="item in cart">
<div class="cart__product-info">
<p></p>
<p class="item__title">Product: {{ item.title }}</p>
<p class="item__quantity">Quantity: {{ item.quantity }}</p>
</div>
</div>
</div>
</section>
</template>
<script>
import {EventBus} from "@/event-bus.js";
export default {
name: "ShoppingCart",
data() {
return {
cart: null
}
},
created() {
EventBus.$on('update-cart', (item) => {
this.cart = item;
});
}
}
products.json
[
{
"category": {
"0": {
"title": "Living Room",
"id": 1
"products": {
"0": {
"title": "Red Seat",
"id": 1,
"description": "Armless Task Chair with Adjustable Height and Swivel Functionality. Comfortable 2 inches thick cushioned back and seat. 360 degrees swivel functionality. Pneumatic seat height adjustment. Upholstered in an easy to clean fabric. Dual wheel caster for any type of flooring",
"price": "45",
"image": "images/redseat.png",
"quantity": 1
},
"1": {
"title": "White Table",
"id": 2,
"description": "International Concepts Solid Wood Dining Table with Shaker Legs",
"price": "350",
"image": "images/whitetable.png",
"quantity": 1
}
}
}
}
]