[SOLVED] Communication between children components: Show / Hide shopping cart using emit from a button in other component

Issue

This Content is from Stack Overflow. Question asked by Farid

I’m working on a shopping cart using vue3 with inertiajs and Laravel and page layout demands to have a main menu with a bag button which on click fires showing and hiding cart event.
So as menu and cart are children component from main page, I guess that the goal is by using communication between components.
I’ve read emit documentation and I can get it working from parent to child and from child to parent, but I can’t achieve the communication between both children components.

I have the following code:

Parent

<Cart :isVisible="showCart" @hideCart="showCart = false" />

<script>
export default { 
  data() {
    return {
      showCart: false,
    }
  },
  methods: {
    toggleCart() {
      this.showCart = !this.showCart    
    },
  }
}
</script>

Menu

<button @click="$emit('toggleCart')"><Icon name="bag" class="w-4" /></button>

Cart

<template>
<div v-if="isVisible">
    <h3 class="flex justify-between">
        <span class="font-bold">My cart</span>
        <button @click="$emit('toggleCart')" class="text-xl">&times;</button>
   </h3>
  ...html code for cart
</div>
</template>
<script setup>
import { Link } from "@inertiajs/inertia-vue3";
const props = defineProps(["isVisible", "cart"]);
const emit = defineEmits(["toggleCart"]);
</script>



Solution

$emit doesn’t call a method in the parent, you have to handle the $emitted event yourself, usually by calling a method. So in your parent component you should have:

<template>
    <Cart :isVisible="showCart" @toggle-cart="toggleCart"..... />
    <Menu @toggle-cart="toggleCart" ..... />
</template>

<script>
  //...
  methods: {
    toggleCart() {
      this.showCart = !this.showCart    
    },
  //...

</script>

The @toggle-cart= is referring to the emitted event, the "toggleCart" is referring to the method in your parent component, but there’s no need for them to have the same name. You could have @toggle-cart="handleCartToggle" as long as handleCartToggle is your method name.
(Note: The kebab-case @toggle-cart instead of @toggleCart is how Vue recommends you refer to events in the template, to align with HTML attributes. Still use toggleCart in the Cart component.


This Question was asked in StackOverflow by Farid and Answered by Yitz It is licensed under the terms of CC BY-SA 2.5. - CC BY-SA 3.0. - CC BY-SA 4.0.

people found this article helpful. What about you?