Is it possible to return a value from the $emit?

21 views Asked by At

I have a child component calling Parent using $emit. How can we get a return value back from the $emit ?

I tried to return a value as well as include a variable in the function and neither of them work. Is it the nature of the $emit function that can't return a value? Are there any workarounds ?

Child:

let data = null;

await this.$emit('loadData', this.Id, data);

Parent:

 async loadData(Id, data) {
 
    let newData = await this.$store.dispatch('user/loadUserData', Id);
   
    data = { ...newData };
}
2

There are 2 answers

0
Alexander Nenashev On BEST ANSWER

You don't need to return from $emit. Usually you mutate a parent's state on events emitted by its child. Then a child use the parent's state to update itself for example through props. That's how v-model works btw:

VUE SFC PLAYGROUND

If you want to get a value from a parent, just call its method:

VUE SFC PLAYGROUND

Parent:

<script setup>
import { ref } from 'vue';
import Comp from './Comp.vue';

const rows = ref([]);
const counter = ref(0);
defineExpose({getRow(){ return 'Row ' + ++counter.value}});

</script>

<template>
  <comp />
</template>

Child:

<script setup>
import {ref} from 'vue';
const rows = ref([]);
</script>

<template>
  <div v-for="row in rows">{{ row }}</div>
  <div>
    <button @click="rows.push($parent.getRow())" >Add row</button>
  </div>
</template>

You can also use provide/inject:

VUE SFC PLAYGROUND

0
puelo On

You can emit arguments with the event. It is explained in the official guide. They have this example:

MyButton component:

<button @click="$emit('increaseBy', 1)">
  Increase by 1
</button>

Parent:

<MyButton @increase-by="increaseCount" />


function increaseCount(n) {
  count.value += n
}

They also state:

All extra arguments passed to $emit() after the event name will be forwarded to the listener. For example, with $emit('foo', 1, 2, 3) the listener function will receive three arguments.