vue.js - 对象的属性已更新,但没有新对象被推送到数组中(购物车、单个文件组件)
问题描述
我遇到了一个问题。我正在尝试编写购物车代码。我有 4 个组件:
- LivingRoom.vue(显示 Product 中的所有产品)
- Product.vue(每个产品的名称、描述和价格的模板),
- ProductDetails.vue(每个产品的详细信息)
- 购物车.vue。
ProductDetails 中的每个产品都有带有addToCart
功能的按钮,该按钮作为参数 item 属性。每次我尝试向数组中添加一个新产品(对象)时,前一个可能会被新的替换。我使用 制作每个对象的深层副本Vue.util.extend
,以便更新数量属性。这很好用。但是当我尝试将不同的项目添加到购物车数组时,前一个项目会消失并且新的项目会显示。我正在使用 EventBus,并且购物车从 ProductDetails 组件发送到 ShoppingCart 组件。
我通过使用这个 codepen 帮助了自己:https ://codepen.io/anon/pen/BEEwqd 一切正常。
我正在从本地(静态/products.json)获取数据。
我尝试将项目从 github 导入到 codesandbox 以使您的一切更轻松,但不知何故它无法按预期工作,因此我将链接粘贴到我的仓库:
https://github.com/rafalpyska/weeklywebdevchallange10
客厅.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;
}
}
产品.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>
产品详情.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>
购物车.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;
});
}
}
产品.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
}
}
}
}
]
解决方案
cart: []
每个总是一个空数组ProductDetails
?所以当你把一个项目推到它上面时,最大长度是 1
一种可能的解决方案是更改update-cart
侦听器
EventBus.$on('update-cart', (item) => {
const newItem = item[0]
this.cart = this.cart || []
let found = false
this.cart = this.cart.map(oldItem => {
if (oldItem.id === newItem.id) {
found = true
return newItem
}
return oldItem
})
if (!found) {
this.cart = this.cart.concat(item)
}
});
推荐阅读
- reactjs - React @material-ui/core - v4.11.0 - “createMuiTheme 函数被重命名为 createTheme” 控制台错误
- mongodb - 如何使用 go mongo 驱动程序获取和检查 mongodb 索引选项
- ethereum - 如何将收获代币添加到农业合同中?
- javascript - 带有 proto loader 问题的 GRPC 连接设置
- postgresql - 使用 SSH 堡垒将 dbt 连接到 Postgres
- entity-framework - 试图在 asp.net mvc5 中创建一个电子商务网站
- javascript - Postman中获取二进制数据的响应成功,但在控制台中返回未定义
- grpc - GRPC 应用程序的身份验证和授权
- excel - VBA 代码:提醒电子邮件不起作用,也没有给出任何错误?
- javascript - 在树视图控件asp.net中搜索无限的子节点和节点