Home > Mobile >  Communication between children components: Show / Hide shopping cart using emit from a button in oth
Communication between children components: Show / Hide shopping cart using emit from a button in oth

Time:09-19

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"  /></button>

Cart

<template>
<div v-if="isVisible">
    <h3 >
        <span >My cart</span>
        <button @click="$emit('toggleCart')" >&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>

CodePudding user response:

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

  • Related