1
votes

I'm trying to call an $emit event from a child component in Vue to trigger a function in App.vue. The event is triggering according to the Vue inspector and the DOM inspector shows the DIV is set to trigger on the event, but nothing happens.

I have tried renaming the event, making sure the functions work on a click event, binding to different components and divs, and including no payload with the event. Nothing seems to work. I've tried both Firefox and Chrome and both end with the same result: Called event with nothing happening.

Child component and method

<div class="navbutton" v-on:click="clicked(data.id)">
  <p>{{data.text}}</p>
</div>
clicked(id){
switch(id){
    case 1:
       alert("One");
       break;
    case 2:
        this.$emit('testemit');
        break;
    case 3:
        alert("Three");
        break;
    case 4:
        alert("Four");
        break;
    default:
        alert("DEFAULT");
        break;
    }
}

From App.vue

<div v-on:testemit="EmitFunction"></div>
EmitFunction() {
    alert('MESSAGE');
}

I expect to receive an alert saying 'MESSAGE' when clicking on the second button, however, nothing happens. The three other buttons (1, 3, & 4) work correctly.

1
In App.vue, you're listening to testemit on div but it should be on the child component, e.g., <my-child v-on:testemit="EmitFunction" />tony19
@tony19 I've already tried that. I have tried calling the event from every component I have in the project.Maple
Your comment below indicates you're emitting the event from a nested child component, but listening to it from App. Note that Vue events are only emitted to the direct parent, and they don't bubble like native events do. To propagate the event up the tree, you'd have to re-emit the event at each level (which could be unwieldy depending on the depth). Consider using an event bus (or state management system, such as Vuex) instead.tony19

1 Answers

1
votes

You need to actually activate an emit and be listening on the parent component, like this:

//app.vue
<template>
  <my-component v-on:testemit="EmitFunction"/>
</template>

and your 'EmitFunction()' is in your methods doing what your 'clicked' is doing.

methods: {
  EmitFunction(id) {
    switch... etc

and in your component...

//myComponent.vue
<div class="navbutton" v-on:click="$emit('testemit', id)">
  <p>{{data.text}}</p>
</div>