How to replace this.$parent.$emit in Vue 3?

Viewed 12653
4 Answers

In your child component:

setup(props, { emit }) {
   ...
   emit('yourEvent', yourDataIfYouHaveAny);
}

Your parent component:

<your-child @yourEvent="onYourEvent" />

...

onYourEvent(yourDataIfYouHaveAny) {
  ...
}

There is similar way of doing it by using the context argument that is passed in second argument inside the child component (the one that will emit the event)

setup(props, context){
     context.emit('myEventName')
}

...then emit it by calling the context.emit method within the setup method.

In your parent component you can listen to it using the handler like so:

<MyParentComponent @myEventName="handleMyEventName" />

Of course, in the setup method of the MyParentComponent component you can declare the handler like this

//within <script> tag of MyParentComponent
setup(props){
    const handleMyEventName() => {
            ...
    }
    return { handleMyEventName }
}

Due to the composition api, it allows you to use the $attrs inherited in each component to now fulfill this need.

I assume that you are using this.$parent.emit because you know the the child will always be part of the same parent. How do I simulate the above behavior with $attrs?

Lets say I have a table containing row components. However I wish to respond to row clicks in table's parent.

Table Definition

 <template>
  <row v-bind="$attrs" ></row>
 </template>

Row Definition

<template name="row" :item="row" @click=onClick(row)>
  Your Row 
</template>

export default {
    emits: {
      row_clicked: () =>{
       return true
      }
   }, 
   onClick(rowData){
     this.$emit('row_clicked',rowData)
  }
}

Finally, a component containing your table definition, where you have a method to handle the click.

<table
@row_clicked=clicked() 
>

</table

Your table component should effectively apply @row_clicked to the row component thus triggering when row emits the event.

Related