Vue 购物车产品变体添加到购物车但购物车中的项目发生变化而不是添加新项目
Vue shopping cart product variations adding to cart but item in cart changes instead of adding new item
我有一个带有 vuex 的 vue 版本“^2.6.11”应用程序,我在其中将项目添加到购物车。
我的商品有颜色等变化,因此在添加到购物车之前我有两个条件,比较颜色和产品 ID。
product.productId == item.productId && product.colour == item.colour
颜色是从 select 框中选择的,产品上的 属性 是通过 select 框中的 selected 颜色更改事件设置的。
this.item.colour = event.target.value
问题是即使颜色发生变化,它也会更新购物车中的当前商品,例如:
Select 框显示金币,单击 "add to cart" 并向购物车添加金币。
Select 框更改为银色,产品组件的颜色 属性 更改为银色并单击 "add to cart"。
购物车中的当前商品数量变为 2 并且其颜色
变成银色。
奇怪的是,当我导航到结帐处然后单击后退按钮时,添加到购物车的工作方式按照我希望的方式进行,方法是将商品的新变体添加到购物车,但是,当我添加另一个商品时之后的变化与第一次一样。
我希望这是有道理的。
我不明白为什么它在单击后退按钮之前不起作用。
I can't set up a Jsfiddle or code snippit because there are so many components working together here so I will add some of my code below.
// Product.vue
<template>
<div>
<b-col>
<b-card
v-bind:title="product_type"
v-bind:img-src="imagePath"
img-alt="Image"
img-top
tag="article"
style="max-width: 15rem;"
class="mb-2">
<b-card-text>{{ product_type }}</b-card-text>
<div class="form-group">
<label for="colourSelect">Please select a colour</label>
<select @change="onChange($event)">
<option v-for="item in metal_colour" v-bind:key="item">
{{ item }}
</option>
</select>
</div>
<div class="clearfix">
<div class="price pull-left" v-bind:key="price">€{{ price }}</div>
<div class="text-right">
<b-button @click="addToCart" variant="primary">Add to cart</b-button>
...
</template>
<script>
export default {
name: 'Product',
props: {
productId: Number,
imagePath: String,
product_type: String,
metal_colour: Array,
price: Number,
qty: Number
},
data() {
return {
item: {
productId: this.productId,
imagePath: this.imagePath,
product_type: this.product_type,
price: this.price,
colour: 'Gold',
qty: 1
}
}
},
methods: {
addToCart() {
this.$store.commit('addToCart', this.item)
this.$bvModal.show('modal-1')
},
onChange(event) {
this.item.colour = event.target.value
}
}
}
</script>
// store/index.js Vuex
...
mutations: {
addToCart(state, item) {
let found = state.inCart.find(
product =>
product.productId == item.productId && product.colour == item.colour
)
if (found) {
found.qty++
} else {
state.inCart.push(item)
}
}
},
...
对于我的购物车,我使用的是模式,商品如下所示:
// Cart.vue
<div>
<b-table striped :items="this.$store.state.inCart">
<template v-slot:cell(imagePath)="data">
<img :src="data.value" class="thumb" alt="product" />
{{ data.imagePath }}
</template>
</b-table>
</div>
<div slot="modal-footer">
<router-link to="/checkout">
<b-button variant="primary" @click="$bvModal.hide('modal-1')">
Checkout
</b-button>
</router-link>
<b-button class="modalBtn" variant="primary" @click="$bvModal.hide('modal-1')">
Continue Shopping
</b-button>
</div>
您在 <template>
标记中使用了 this
> this.$store.state.inCart
,应该只是 $store.state.inCart
,但无论如何都应该标记错误并且永远不会真正起作用。
<b-table striped :items="$store.state.inCart">
您可能遇到了反应问题,请试试这个:
import {mapState} from 'vuex'
computed: {
...mapState(['inCart'])
}
<b-table striped :items="inCart">
最后,当您将商品添加到购物车时,您需要添加 item
对象的 COPY,因为您通过引用传递对象并由于执行 state.inCart.push(item)
.
有两种选择:
1) 导入 lodash
> import { copy } from 'lodash'
并使用 copy(item)
2) JSON.parse(JSON.stringify(item))
看起来很脏但是速度很快
这两种方法将取消引用对象。
澄清一下,您可以在 vuex
addToCart
方法中执行此复制过程:
addToCart(state, item) {
let found = state.inCart.find(
product => product.productId === item.productId && product.colour === item.colour
)
if (found) {
found.qty++
} else {
// Clone the object.
const insert = JSON.parse(JSON.stringify(item))
state.inCart.push(insert)
}
}
我有一个带有 vuex 的 vue 版本“^2.6.11”应用程序,我在其中将项目添加到购物车。 我的商品有颜色等变化,因此在添加到购物车之前我有两个条件,比较颜色和产品 ID。
product.productId == item.productId && product.colour == item.colour
颜色是从 select 框中选择的,产品上的 属性 是通过 select 框中的 selected 颜色更改事件设置的。
this.item.colour = event.target.value
问题是即使颜色发生变化,它也会更新购物车中的当前商品,例如:
Select 框显示金币,单击 "add to cart" 并向购物车添加金币。
Select 框更改为银色,产品组件的颜色 属性 更改为银色并单击 "add to cart"。
购物车中的当前商品数量变为 2 并且其颜色 变成银色。
奇怪的是,当我导航到结帐处然后单击后退按钮时,添加到购物车的工作方式按照我希望的方式进行,方法是将商品的新变体添加到购物车,但是,当我添加另一个商品时之后的变化与第一次一样。
我希望这是有道理的。 我不明白为什么它在单击后退按钮之前不起作用。
I can't set up a Jsfiddle or code snippit because there are so many components working together here so I will add some of my code below.
// Product.vue
<template>
<div>
<b-col>
<b-card
v-bind:title="product_type"
v-bind:img-src="imagePath"
img-alt="Image"
img-top
tag="article"
style="max-width: 15rem;"
class="mb-2">
<b-card-text>{{ product_type }}</b-card-text>
<div class="form-group">
<label for="colourSelect">Please select a colour</label>
<select @change="onChange($event)">
<option v-for="item in metal_colour" v-bind:key="item">
{{ item }}
</option>
</select>
</div>
<div class="clearfix">
<div class="price pull-left" v-bind:key="price">€{{ price }}</div>
<div class="text-right">
<b-button @click="addToCart" variant="primary">Add to cart</b-button>
...
</template>
<script>
export default {
name: 'Product',
props: {
productId: Number,
imagePath: String,
product_type: String,
metal_colour: Array,
price: Number,
qty: Number
},
data() {
return {
item: {
productId: this.productId,
imagePath: this.imagePath,
product_type: this.product_type,
price: this.price,
colour: 'Gold',
qty: 1
}
}
},
methods: {
addToCart() {
this.$store.commit('addToCart', this.item)
this.$bvModal.show('modal-1')
},
onChange(event) {
this.item.colour = event.target.value
}
}
}
</script>
// store/index.js Vuex
...
mutations: {
addToCart(state, item) {
let found = state.inCart.find(
product =>
product.productId == item.productId && product.colour == item.colour
)
if (found) {
found.qty++
} else {
state.inCart.push(item)
}
}
},
...
对于我的购物车,我使用的是模式,商品如下所示:
// Cart.vue
<div>
<b-table striped :items="this.$store.state.inCart">
<template v-slot:cell(imagePath)="data">
<img :src="data.value" class="thumb" alt="product" />
{{ data.imagePath }}
</template>
</b-table>
</div>
<div slot="modal-footer">
<router-link to="/checkout">
<b-button variant="primary" @click="$bvModal.hide('modal-1')">
Checkout
</b-button>
</router-link>
<b-button class="modalBtn" variant="primary" @click="$bvModal.hide('modal-1')">
Continue Shopping
</b-button>
</div>
您在 <template>
标记中使用了 this
> this.$store.state.inCart
,应该只是 $store.state.inCart
,但无论如何都应该标记错误并且永远不会真正起作用。
<b-table striped :items="$store.state.inCart">
您可能遇到了反应问题,请试试这个:
import {mapState} from 'vuex'
computed: {
...mapState(['inCart'])
}
<b-table striped :items="inCart">
最后,当您将商品添加到购物车时,您需要添加 item
对象的 COPY,因为您通过引用传递对象并由于执行 state.inCart.push(item)
.
有两种选择:
1) 导入 lodash
> import { copy } from 'lodash'
并使用 copy(item)
2) JSON.parse(JSON.stringify(item))
看起来很脏但是速度很快
这两种方法将取消引用对象。
澄清一下,您可以在 vuex
addToCart
方法中执行此复制过程:
addToCart(state, item) {
let found = state.inCart.find(
product => product.productId === item.productId && product.colour === item.colour
)
if (found) {
found.qty++
} else {
// Clone the object.
const insert = JSON.parse(JSON.stringify(item))
state.inCart.push(insert)
}
}