Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

arthur007's avatar

how to make an emit works instantly in laravel 9 vuejs 3?

I'm trying to get familiar with laravel9, vuejs3 and vite with a simple ecommerce website the problem is when I click add to carte its work fine but the count in icon carte incrementing but till I reload the page. this my add to carte component

<template>
      <div class="flex items-center justify-between py-4">
        <button
            class=" bg-orange-700 text-black rounded-md cursor-pointer text-xs font-semibold px-3 py-2 m-4 "
            v-on:click.prevent="addToCart"
        >
            Ajouter au panier
        </button>
    </div>
</template>

<script setup >
import useProduct from '../composables/products'
import axios from 'axios';
import Emitter from 'pico-emitter';


    const {add} = useProduct()
    const productId = defineProps(['productId'])


    const emitter = new Emitter();
    
    const addToCart= async()=>{
        await axios.get('/sanctum/csrf-cookie');
                await axios.get('/api/user')
                .then(async(res)=>{
                    let cartCount= await add(productId);
                    emitter.emit('refreshCartCount',cartCount);
                    console.log(cartCount)
                })
                .catch(err=>console.log(err));

    }

</script>

and navbare cart component I used tiny-emitter but it doesn't worked correctly so I tried a similar package pico-emitter

<template>
        <div class="hidden space-x-8 sm:-my-px sm:ml-10 sm:flex mr-10">
        <a href="/shoppingCart" class="relative">
            <span class="absolute -top-1 left-4 rounded-full bg-indigo-700 w-5 h-5 text-xs text-white flex items-center justify-center">{{ cartCount }}</span>
            <svg xmlns="http://www.w3.org/2000/svg" class="h-7 w-7 text-sm font-medium leading-5 text-gray-600 " fill="none" viewBox="0 0 24 24" stroke="currentColor" stroke-width="2">
            <path stroke-linecap="round" stroke-linejoin="round" d="M16 11V7a4 4 0 00-8 0v4M5 9h14l1 12H4L5 9z" />
            </svg>
        </a>
    </div>
</template>


<script setup>
import Emitter from 'pico-emitter';
import {onMounted,ref} from 'vue';
import useProduct from '../composables/products'; 


const {getCount}= useProduct();
const cartCount=ref(0)

const emitter = new Emitter();

emitter.on('refreshCartCount',function(count){
    cartCount.value = count
});


onMounted(async()=>{

 cartCount.value = await getCount();
   
     console.log(cartCount.value)

});

</script>
0 likes
2 replies
apox's avatar
apox
Best Answer
Level 1

Hi! I'm not really familiar with the pico-emitter library but I'm pretty sure the problem is that you're creating two seperate instances of it.

You're calling const emitter = new Emitter(); in both components, resulting in two completely seperate instances of the event bus. So basically you're listening to an event that happens on the other instance.

The solution would probably be to create a seperate file that initiates the emitter once (maybe call it eventbus.js or something similar) and exports the instance.

import Emitter from 'pico-emitter';
export default new Emitter();

Then in all of your components, import your own file instead of the library. Like this you will always have a single emitter instance throughout all components.

import emitter from '../eventbus';

emitter.emit(...)
emitter.on(...)

All code is untested, but I hope this helps ;)

1 like
arthur007's avatar

@apox it works like magic thank you, I've been struggling with it for 2 days

1 like

Please or to participate in this conversation.