网站首页 > 精选文章 正文
声明触发的事件
为了让组件的用法更清晰(作为文档),同时让 Vue 能区分事件与透传 attribute,推荐显式声明组件要触发的事件。根据组件是否使用 <script setup>,声明方式有所不同。
使用 <script setup>时:defineEmits()宏
在 <script setup> 中,需通过 defineEmits() 宏声明事件。该宏无需导入,直接使用,返回一个与 $emit 作用相同的 emit 函数,供 <script> 中触发事件使用。
基础声明(数组形式)
<script setup>
// 声明组件会触发 inFocus 和 submit 事件
const emit = defineEmits(['inFocus', 'submit'])
// 在脚本中通过 emit 函数触发事件
function buttonClick() {
emit('submit') // 触发 submit 事件,与模板中 $emit 效果一致
}
</script>
注意:defineEmits() 必须直接放在 <script setup> 的顶级作用域中,不能在子函数内使用。
对象形式声明(支持参数校验)
defineEmits() 还支持对象形式声明,可通过函数对事件的参数进行校验(后续“事件校验”章节详细讲解)。若搭配 TypeScript,还能为参数指定类型:
<script setup lang="ts">
// 对象形式声明:submit 事件需接收 { email: string, password: string } 类型的参数
const emit = defineEmits({
submit(payload: { email: string, password: string }) {
// 返回 true 表示校验通过,false 表示失败
return payload.email && payload.password // 简单校验:邮箱和密码都存在则通过
}
})
</script>
TypeScript 类型标注声明
若使用 TypeScript + <script setup>,可通过纯类型标注声明事件,语法更简洁,类型约束更严格:
<script setup lang="ts">
// 类型标注声明:定义事件的名称和参数类型
const emit = defineEmits<{
(e: 'change', id: number): void // change 事件需传递 number 类型的 id
(e: 'update', value: string): void // update 事件需传递 string 类型的 value
}>()
// 触发事件时,TypeScript 会自动校验参数类型
emit('change', 123) // 正确:id 是 number 类型
emit('update', 'hello') // 正确:value 是 string 类型
// emit('change', 'abc') // 错误:TypeScript 会提示参数类型不匹配
</script>
不使用 <script setup>时:emits选项
若未使用 <script setup>,需在组件选项中通过 emits 选项声明事件,同时 emit 函数会暴露在 setup() 的上下文对象(ctx)中。
基础用法
export default {
// 声明会触发的事件(数组形式)
emits: ['inFocus', 'submit'],
setup(props, ctx) {
// 通过 ctx.emit 触发事件
ctx.emit('submit')
}
}
解构 emit函数
setup() 上下文对象的 emit 可安全解构,简化使用:
export default {
emits: ['inFocus', 'submit'],
// 解构 ctx 中的 emit
setup(props, { emit }) {
emit('submit') // 直接使用 emit 函数
}
}
声明事件的意义
显式声明事件虽非强制,但有重要作用:
- 作为组件文档:清晰告知使用者组件会触发哪些事件,提升代码可读性和可维护性。
- 区分事件与透传 attribute:Vue 会根据声明的事件过滤透传 attribute(避免将事件名当作 HTML 属性传递给子组件的根元素)。
- 屏蔽原生事件冲突:若原生事件名(如 click)被声明在 emits 中,父组件的监听器只会响应子组件触发的 click 事件,不再响应子组件根元素的原生 click 事件——避免了事件来源的混淆。
事件校验
与 props 类似,组件事件也可进行校验:通过在事件声明中定义函数,验证 emit 传递的参数是否合法。若校验失败,可在控制台抛出警告,帮助开发者发现问题。
事件校验的实现
在对象形式的事件声明中,将事件名对应的 value 设为一个函数:该函数接收 emit 传递的参数,返回 true(校验通过)或 false(校验失败)。
<script setup>
// 对象形式声明事件,同时定义校验逻辑
const emit = defineEmits({
// click 事件:null 表示无需校验
click: null,
// submit 事件:定义校验函数
submit: ({ email, password }) => {
// 校验逻辑:邮箱和密码都存在则通过
if (email && password) {
return true // 校验通过
} else {
// 校验失败:打印警告
console.warn('Invalid submit event payload! 邮箱和密码不能为空')
return false
}
}
})
// 触发 submit 事件的函数
function submitForm(email, password) {
emit('submit', { email, password }) // 传递参数,触发校验
}
</script>
当调用 submitForm('test@example.com', '123456') 时,参数符合校验规则(邮箱和密码都存在),校验通过;若调用 submitForm('', ''),则校验失败,控制台会输出警告。
校验函数的作用
事件校验主要用于开发阶段,帮助规范子组件向父组件传递的数据格式。例如:确保表单提交事件传递的参数包含必要字段(如邮箱、密码),避免父组件因接收无效数据而出现错误。生产环境中,校验逻辑不会影响事件的触发(即使校验失败,事件仍会被父组件接收),仅作为开发辅助。
通过组件事件,子组件能灵活地向父组件传递信息,而显式声明和校验则让事件交互更规范、可靠。合理使用组件事件,能让组件间的通信清晰且可维护,是构建复杂 Vue 应用的基础技能。
猜你喜欢
- 2025-09-29 Vue3小知识:一篇关于emits的使用指南
- 2025-09-29 vue-particles粒子背景组件,支持服务端渲染
- 2025-09-29 「 VUE3 + TS + Vite 」父子组件间如何通信?
- 2025-09-29 vue3 新特性 computed、watch、watchEffect 看完就会
- 2025-09-29 10个Vue3代码简写技巧_vue代码示例
- 2025-09-29 总结7个实用的Vue自定义指令_vue自定义指令两种方式
- 2025-09-29 【Vue3】插槽(Slots):掌握组件内容分发的艺术
- 2025-09-29 Vue3里面的 ref, computed介绍_vue3 ref用法
- 2025-09-29 Vue基础入门,第21节,表单数据的收集与提交
- 最近发表
- 标签列表
-
- 向日葵无法连接服务器 (32)
- git.exe (33)
- vscode更新 (34)
- dev c (33)
- git ignore命令 (32)
- gitlab提交代码步骤 (37)
- java update (36)
- vue debug (34)
- vue blur (32)
- vscode导入vue项目 (33)
- vue chart (32)
- vue cms (32)
- 大雅数据库 (34)
- 技术迭代 (37)
- 同一局域网 (33)
- github拒绝连接 (33)
- vscode php插件 (32)
- vue注释快捷键 (32)
- linux ssr (33)
- 微端服务器 (35)
- 导航猫 (32)
- 获取当前时间年月日 (33)
- stp软件 (33)
- http下载文件 (33)
- linux bt下载 (33)