1

Suppose we have a child component which emits a custom event iterated. Is there a way to listen to the event in the parent component via this.$ref? Like this.$refs.on('iterated', event). I know I can listen on component via v-on or by using watch, but the documentation says nothing about achieving this on component instance. A simple usecase for this could be an image cropper that emits an event when the cropping is done, to queue the files for multi upload.

Please see the simplified example below.

Child Component

<template>
    <p>Count: {{ count }} </p>
<template>

<script>
    export default {
        data: () => ({
            count: 1
        }),
        mounted () {
            const that = this;
            setTimeout(() => {
                that.count++;
                that.$emit('iterated', that.count);
            }, 2000);
        }
    };
</script>

Parent Component

<template>
    <child-component ref="myChild" />
<template>

<script>
    export default {
        mounted () {
            this.$refs.myChild.on('iterated', (count) => {
                console.log(count);
            });
        }
    };
<script>

// EDIT: This question might be a duplicate (although there is no answer): VueJS 3 : Add event listener through js code

pixelmusik
  • 510
  • 5
  • 19

1 Answers1

1

v-on is how you add handlers to emitted events from child components:

<template>
  <child-component ref="myChild" @iterated="handler" />
</template>

<script>
  export default {
    methods: {
      handler(count) => {
        console.log(count)
      }
    }
  }
</script>

For defining events when using render functions, see the examples in documentation.


Note: under the hood, all event listeners defined as component-emitted events are Custom Events, with the default value for bubbles, which is false.

Documentation: Emitting and Listening to Events:

Unlike native DOM events, component emitted events do not bubble. You can only listen to the events emitted by a direct child component. If there is a need to communicate between sibling or deeply nested components, use an external event bus or a global state management solution.

In short, they are only triggered on the child component, and they do not bubble to the parent or subsequent DOM ancestors.

tao
  • 82,996
  • 16
  • 114
  • 150
  • Thanks @tao. I have already feared that so I went for a custom solution with the npm package `mitt`. My approach is to store the emitter instance in a global vuex store module so I can access the custom events where I need them. I need to access the events in JS for a multi file upload to queue the promises coming from an image cropper. The custom event is fired from the cropper so the parent component knows when the cropping is done to resolve the promise and to init the cropping process for the next file. – pixelmusik Mar 06 '23 at 15:42