You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Vue3中父组件事件处理函数参数无法继承子组件defineEmits类型

解决Vue 3父子组件事件类型不继承问题

问题原因

<script setup lang="ts"> 属于封闭作用域,子组件中定义的事件参数类型默认不会对外暴露,导致父组件的事件处理函数无法自动推导参数类型,只能识别为any。

解决方案

方案一:子组件导出事件参数类型(简单直接)

在子组件中把事件的参数类型用export导出,让父组件可以导入使用:

<script setup lang="ts">
// 导出事件参数类型
export type EventPayload = {
  foo: boolean
}
const emits = defineEmits<{
  'my-event': [EventPayload]
}>()

const onClick = () => {
  emits('my-event', { foo: true})
}
</script>

<template>
  <button @click="onClick" />
</template>

父组件中导入类型并标注给事件处理函数:

<script setup lang="ts">
// 导入子组件的事件参数类型
import type { EventPayload } from './Child.vue'
import Child from './Child.vue'

const onMyEvent = ({ foo }: EventPayload) => {
  console.log(foo) // foo类型自动识别为boolean,无类型错误
}
</script>

<template>
  <Child @my-event="onMyEvent" />
</template>

方案二:利用Vue内置类型提取事件类型(无需子组件额外导出)

如果不想单独导出类型,可以通过Vue内置的ExtractEmits类型提取子组件的事件类型:

// 子组件保持原代码,无需额外导出类型
<script setup lang="ts">
type EventPayload = {
  foo: boolean
}
const emits = defineEmits<{
  'my-event': [EventPayload]
}>()

const onClick = () => {
  emits('my-event', { foo: true})
}
</script>

父组件中提取并使用类型:

<script setup lang="ts">
import Child from './Child.vue'
import type { ExtractEmits } from 'vue'

// 提取子组件的事件类型集合
type ChildEmits = ExtractEmits<typeof Child.emits>
// 获取'my-event'对应的参数类型
type MyEventPayload = Parameters<ChildEmits['my-event']>[0]

const onMyEvent = ({ foo }: MyEventPayload) => {
  console.log(foo)
}
</script>

<template>
  <Child @my-event="onMyEvent" />
</template>

这种方式无需子组件修改,但写法稍复杂,适合需要统一管理组件事件类型的场景。

内容的提问来源于stack exchange,提问作者Existe Deja

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 14:02:13