一聚教程网:一个值得你收藏的教程网站

最新下载

热门教程

Vue3 中 defineEmits 怎么用:手把手教你规范编写子传父逻辑

时间:2026-07-23 10:43:48 编辑:袖梨 来源:一聚教程网

defineEmits是Vue 3中声明子组件事件的关键函数,支持数组/对象写法、v-model双向绑定及TS强类型校验,需显式声明才能触发有效事件。

defineEmits 是 Vue 3 组合式 API 中用于声明子组件可触发事件的关键函数,它替代了 Vue 2 的 emits 选项,让子组件的事件接口更清晰、类型更安全(尤其在 TypeScript 中)。

一、基础用法:声明并触发事件

setup<script setup> 中调用 defineEmits,传入事件名数组或对象,然后通过返回的函数派发事件:

  • 数组写法(适合无参数或简单场景):

<script setup>
  const emit = defineEmits(['update:modelValue', 'change', 'submit'])
  const handleClick = () => {
    emit('change', 'new value') // 触发 change,并传参
  }
</script>

  • 对象写法(推荐,支持类型校验和文档化):

const emit = defineEmits({
  'update:modelValue': (value: string) => typeof value === 'string',
  'submit': (data: { id: number; name: string }) => true
})

立即学习“前端免费学习笔记(深入)”;

✅ 注意:校验函数只需返回布尔值,不抛错;Vue 不会拦截非法调用,但会在开发模式下给出警告。

二、配合 v-model 实现双向绑定

当子组件需要支持 v-model(如自定义输入框),需按约定命名事件:update:xxx。Vue 会自动将 v-model="xxx" 编译为 :xxx="xxx" @update:xxx="val => xxx = val"

  • 声明支持 v-model 的 prop 名(默认是 modelValue)和对应事件
  • 触发 update:modelValue 事件更新父级数据

<script setup>
  const props = defineProps({ modelValue: String })
  const emit = defineEmits(['update:modelValue'])
  const handleChange = (e: Event) => {
    emit('update:modelValue', (e.target as HTMLInputElement).value)
  }
</script>
<template>
  <input :value="props.modelValue" @input="handleChange" />
</template>

三、TypeScript 下的强类型保障

搭配 defineEmits 的泛型,可让事件参数具备完整类型推导(VS Code 可提示、编译期检查):

const emit = defineEmits<{
  (e: 'change', value: string): void
  (e: 'error', code: number, msg: string): void
  (e: 'init', config: Record<string, any>): void
}>()

  • 每个元组表示一个事件签名:(e: '事件名', ...args)
  • 父组件监听时,IDE 能精准提示参数个数与类型
  • 调用 emit('change') 少传/错传参数,TS 会直接报错

四、常见误区与建议

  • ❌ 不要省略 defineEmits 声明就直接调用 emit —— 否则事件不会被父组件捕获(Vue 3 默认关闭未声明事件的透传)
  • ❌ 避免用字符串拼接生成事件名(如 emit(`update:${key}`)),这会破坏类型检查和 IDE 支持
  • ✅ 多事件共用同一参数结构?可提取类型别名复用
  • ✅ 子组件只负责“通知”,不处理业务逻辑 —— 事件语义应清晰(如 'item-added' 而非 'click'

热门栏目