Answer the question
In order to leave comments, you need to log in
How can I tell if a product has been added to the cart?
There is a catalog component, a product module, and something remotely resembling a shopping cart. Product module - stores a list of all products, and the order module - Id of the purchased product and quantity. How to determine that the "Buy" button of a particular product has been clicked, display a message about this and make the button invalid (disabled)?
Catalog.vue
<template>
<b-row>
<b-col sm="6" lg="4" xl="3" v-for="product in products" :key="product.id">
<div class="image" v-lazy:background-image="product.image">
Видно если нажали "Купить".
</div>
<div class="d-flex justify-content-between">
<div>
<p class="mb-0">{{product.name}}</p>
<p class="mb-0">{{product.price}} грн.</p>
</div>
<b-button class="align-self-center" variant="outline-dark" @click="buyProduct(product.id)">Купить</b-button>
</div>
</b-col>
</b-row>
</template>
<script lang="javascript">
import { BRow, BCol, BButton } from 'bootstrap-vue'
import { mapState, mapActions } from 'vuex'
export default {
components: {
BRow,
BCol,
BButton
},
computed: mapState({
products: state => state.product.all
}),
methods: {
...mapActions('order', ['buyProduct'])
}
}
</script>
import axios from 'axios'
export default {
namespaced: true,
strict: true,
state: {
page: 1,
all: []
},
mutations: {
incrementPage: (state) => {
state.page++
},
addToAllProducts: (state, products) => {
state.all.push(...products)
}
},
actions: {
getFourProducts: (context, $state) => {
axios.get('http://api.local/api/products', {
params: {
page: context.state.page
},
}).then(({ data }) => {
if (data.data.length) {
context.commit('incrementPage')
context.commit('addToAllProducts', data.data)
$state.loaded()
} else {
$state.complete()
}
})
}
}
}
export default {
namespaced: true,
strict: true,
state: {
all: []
},
mutations: {
addToOrder(state, id) {
state.all.push({
id,
quantity: 1
})
}
},
actions: {
buyProduct(context, id) {
context.commit('addToOrder', id)
}
}
}
Answer the question
In order to leave comments, you need to log in
Let's add a property to the products elements that will indicate whether the product is present in the cart. To do this, we rewrite it as follows:
computed: mapState({
products: state => state.product.all.map(n => ({
...n,
isOrdered: state.order.all.some(m => m.id === n.id),
})),
}),
<b-button :disabled="product.isOrdered"
computed: {
isOrdered() {
return Object.fromEntries(this.$store.state.order.all.map(n => [ n.id, true ]));
},
},
product.isOrdered
of the previous version, there will be isOrdered[product.id]
. <template>
<b-row>
<b-col sm="6" lg="4" xl="3" v-for="product in products" :key="product.id">
<div class="image" v-lazy:background-image="product.image">
Видно если нажали "Купить".
</div>
<div class="d-flex justify-content-between">
<div>
<p class="mb-0">{{product.name}}</p>
<p class="mb-0">{{product.price}} грн.</p>
</div>
<b-button class="align-self-center" variant="outline-dark" @click="buyProduct(product)">Купить</b-button>
</div>
</b-col>
</b-row>
</template>
<script lang="javascript">
import { BRow, BCol, BButton } from 'bootstrap-vue'
import { mapState, mapActions } from 'vuex'
export default {
components: {
BRow,
BCol,
BButton
},
computed: mapState({
products: state => state.product.all
}),
methods: {
buyProduct(product){
console.log(product)
}
}
}
</script>
<b-button class="align-self-center" variant="outline-dark" @click.once="buyProduct(product.id)">Купить</b-button>
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question