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
相关产品推荐
相关产品推荐

