I have a vue version "^2.6.11" app with vuex where I am adding items to the cart. My items have variations like colour so I have two conditions before adding to cart comparing the colour and the product ID.
product.productId == item.productId && product.colour == item.colour
The colour is chosen from a select box, a property on the product is set with the selected colour on change event from the select box.
this.item.colour = event.target.value
The problem is that it updates the current item in the cart even if the colour is changed for example:
Select box displays gold, "add to cart" is clicked and a gold item is added to cart.
Select box is changed to silver, the product component changes its colour property to silver and "add to cart" is clicked.
The current item in the cart quantity changes to 2 and its colour changes to silver.
The odd thing is when I navigate to the checkout then click the back button, the add to cart works the way I want it to by adding the new variation of the item to the cart, however, when I add another variation after that it works as it did the first time.
I hope this makes sense. I don't understand why it doesn't work prior to click the back button.
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)
}
}
},
...
For my shopping cart I am using a modal and the items are listed as follows:
// 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>