The naive way to do it…
Child component (event bubbled from)
<!-- ChildComponent.vue -->
<template>
<button @click="handleClick">Click Me!</button>
</template>
<script setup>
import { defineEmits } from 'vue'
const emits = defineEmits(['clicked'])
function handleClick() {
emits('clicked', 'Some data')
}
</script>
Intermediate component
<!-- IntermediateComponent.vue -->
<template>
<ChildComponent @clicked="handleClicked" />
</template>
<script setup>
import ChildComponent from './ChildComponent.vue'
import { defineEmits } from 'vue'
const emits = defineEmits(['clicked'])
function handleClicked(data) {
// Bubble up the event to the parent of the WrapperComponent
emits('clicked', data)
}
</script>
Parent component
<!-- ParentComponent.vue -->
<template>
<div>
<IntermediateComponent @clicked="onChildClicked" />
</div>
</template>
<script setup>
function onChildClicked(data) {
console.log('Event data from child:', data)
}
</script>
The more straightforward way to do it
<!-- IntermediateComponent.vue -->
<template>
<ChildComponent v-bind="$attrs" @update:modelValue="handleModelUpdate" />
</template>
<script setup>
import ChildComponent from './ChildComponent.vue'
import { defineEmits } from 'vue'
// Emit function that captures all event names
const emits = defineEmits()
function handleModelUpdate(value) {
emits('update:modelValue', value)
}
</script>