Skip to content
Advertisement

Pass selected index of object that resides outside of a v-for loop in Vue 3

I’m creating a simple shopping cart in Vue 3 for learning purposes.

So far, I’ve set up everything from the products object to the addToCart() functionality, and everything works within a v-for loop.

The problem is I need to display the product’s title within an alert that resides outside the v-for loop and I have no idea how to do that in Vue.

I tried emit and provide but it’s not working. I can send the entire object to the child component Alert.vue via provide but that’s not helpful as I only need to get the current index of the selected product to be able to fetch its title.

You can check a demo here https://codesandbox.io/s/vue-cart-54ioqt?file=/src/App.vue

Try adding a product to the cart twice and check the Alert. At the moment it’s displaying the entire cart object but I only need to fetch the title of the product so that the alert would say You have already added {product.title} to your cart

App.vue

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
        }
    }
}

Alert.vue (child component)

<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>

Advertisement

Answer

You can show your prop product in Cart component:

You have already added this {{ product }} to your cart.

In app add item to data function:

item: null

in method add title to that data property:

this.item = this.products[index].title
this.alreadyAddedToCart = true;

in template bind your property to item:

:product="item"

your demo

Advertisement