How to bubble up event in Composition Api Vue 3

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>