For educational purposes, I am working on building a basic shopping cart using Vue 3.
So far, I have successfully set up the products
object and implemented the addToCart()
functionality. Everything is functioning smoothly within a v-for
loop.
However, the challenge arises when I attempt to display the title of the product in an alert outside the v-for
loop. I am unsure of how to achieve this in Vue.
I have experimented with emit
and provide
, but so far they have not yielded the desired results. While using provide
allows me to send the entire object to the child component Alert.vue
, it does not solve my specific need, which is to retrieve the current index of the selected product in order to fetch its title.
You can view a demo of the project here.
To see the issue firsthand, try adding a product to the cart twice and observe the Alert message. Currently, it displays the entire cart object instead of just stating "
You have already added {product.title} to your cart
" as intended.
Here's a snippet of the code:
export default {
name: 'App',
components: {
CartAlert
},
data() {
return {
products: [
{id: 1, title: 'Samsung A70', price: 50},
{id: 2, title: 'Kindle Reader', price: 50},
{id: 3, title: 'Meta Quest 2', price: 100},
{id: 4, title: 'LG LED 43" TV', price: 200},
],
discountInput: '',
discountValid: false,
cart: [],
total: '',
alreadyAddedToCart: false
}
},
methods: {
addToCart(index) {
if (this.cart.includes(this.products[index])) {
this.alreadyAddedToCart = true
} else {
this.cart.push(this.products[index])
}
},
},
provide() {
return {
cart: this.cart
}
}
}
In the Alert.vue
component (child component), the code looks like this:
<template>
<div id="alert" class="alert alert-danger alert-dismissible fade show" role="alert">
You have already added this {{ cart }} to your cart.
<button type="button" class="btn-close" data-bs-dismiss="alert" aria-label="Close"
@click="$emit('dismissAlert')"></button>
</div>
</template>
<script>
export default {
name: "CartAlert",
props: ['product'],
inject: ['cart'],
mounted() {
console.log()
}
}
</script>