前言:不懂在父组件里对子组件 @xxxx 声明自定义事件,就不用看本篇文章了。本篇对此内容不做任何说明。这是与 emits 结合使用的必备知识!
<childComp @emitEvnentName='deleteFn'></childComp>
emits
场景说明:
组件功能封装:
组件封装了一系列 emit 事件,并返回数据、回调函数等,或单纯执行某个操作后,触发父组件的事件响应。
外部要用时,使用 @xxxx 来接收使用、响应。
-
类型:
Array<string> | Object
-
详细:
emits 可以是数组或对象,从组件触发自定义事件,emits 可以是简单的数组,也可以是对象,后者允许配置事件验证。
在对象语法中,每个 property 的值可以为
null
或验证函数。验证函数将接收传递给$emit
调用的其他参数。如果this.$emit('foo',1)
被调用,foo
的相应验证函数将接收参数1
。验证函数应返回布尔值,以表示事件参数是否有效。
数组写法:// emits:['emitEvnentName']
对象写法:// emits:{}
{ eventName:null }
{ eventName:()=>{} }
细节说明:
1、数组形式和对象形式的值为null,表示该emit事件无验证函数。
2、对象形式且值为函数表示该 emit 配置了事件验证
验证函数必须有 return 真假值,真值表示通过验证,假值则 vue 会自动抛出 warn 警告!不 return 值默认当做失败,抛出 warn 警告!
验证函数主要就是验证参数是否正确,并不会在 return false 时中断 emit() 事件!// 子组件 <template> <el-button type="success" plain @click='trigger'>emits测试</el-button> </template> <script lang="ts"> import { defineComponent } from 'vue' export default defineComponent({ // 定义自定义事件 // emits:['emitEvnentName'], // 数组写法都默认无验证函数!! emits: { noVerification: null, // 无验证函数 emitEvnentName: ({ email, password },data2,dataX) => { console.log('定义自定义事件-myEvent',email, password,data2,dataX); if (email && password) { // 验证函数应返回布尔值,以表示事件参数是否有效。 return true } else { console.error('Invalid submit event payload!') return false } } }, methods:{ trigger(){ let email = 1 let password = null this.$emit('emitEvnentName',{email, password},'data2',['data3','data4']) } } }) </script>
$emit
-
参数:
{string} eventName
[...args]
触发当前实例上的事件。附加参数都会传给监听器回调。
父组件自定义的事件名作为$emit的第一个参数,第二个参数开始就是传给绑定事件的参数,可以传多个参数。
其他没啥好说的了。。就只是触发事件罢了。
使用方法:(结合上面代码片段的案例,且父组件声明了 @emitEvnentName 自定义事件)
this.$emit('emitEvnentName',{email, password},'data2',['data3','data4'])
# composition Api 写法:defineEmits
在 <script setup> 中必须使用 defineProps 和 defineEmits API 来声明 props 和 emits ,它们具备完整的类型推断并且在 <script setup> 中是直接可用的:
<script setup>
const emit = defineEmits(['change', 'delete'])
</script>
defineEmits 是只在 <script setup> 中才能使用的编译器宏。他们不需要导入且会随着 <script setup> 处理过程一同被编译掉。
defineEmits 在选项传入后,会提供恰当的类型推断。
传入到 defineProps 和 defineEmits 的选项会从 setup 中提升到模块的范围。因此,传入的选项不能引用在 setup 范围中声明的局部变量。这样做会引起编译错误。但是,它可以引用导入的绑定,因为它们也在模块范围内。
以下为错误写法!!
let enFn = (val) => { console.log('定义自定义事件-delete',val); if (val) { return true } else { console.error('Invalid submit event payload!') return false } } const emit = defineEmits({ noVerification: null, // 无验证函数 delete: enFn // 会编译报错 })
defineEmits 也接收 emits 选项相同的值。效果跟options emits里的{} 一样,此处只展示写法,功能讲解的内容,忘了就请回看上面的 options 写法里的讲解!!
<script setup> const emit = defineEmits({ noVerification: null, // 无验证函数 delete: (val) => { console.log('定义自定义事件-myEvent',val); if (val) { return true } else { console.error('Invalid submit event payload!') return false } } }) console.log(emit); setTimeout(() => { emit('delete','测试') }, 1000*10); </script>
如果使用了 Typescript,使用纯类型声明来声明 prop 和 emits 也是可以的。
# ts 类型声明写法:
defineProps 或 defineEmits 只能是要么使用运行时声明,要么使用类型声明。同时使用两种声明方式会导致编译报错。
讲解:左边的相当于函数参数名,第一个参数的值就是emit事件名,后面的任意多个参数都是emit事件的传递参数内容。剩下的就是TS相关内容,此处不对TS进行深入讲解,不懂的自己去学。
这里函数的参数名叫什么不重要,重要的是`ts类型`!第一个参数的ts类型值是`emit 事件名`,后面的参数 ts类型 则是emit传递的参数类型验证!提供编辑器报错功能。
<script setup lang='ts'>
const emit = defineEmits<{
(e: 'change', id: number): void
(e: 'delete', value: string, vlaue2:number ,value3?:boolean): void
}>()
setTimeout(() => {
emit('delete', '123', 5666)
}, 1000*4);
</script>
使用类型声明的时候,静态分析会自动生成等效的运行时声明,以消除双重声明的需要并仍然确保正确的运行时行为。
场景说明:
组件功能封装:
组件封装了一系列 emit 事件,并返回数据、回调函数等,或单纯执行某个操作后,触发父组件的事件响应。
外部要用时,使用 @xxxx 来接收使用、响应。
QQ交流群:522976012 ,欢迎来玩文章来源:https://www.toymoban.com/news/detail-407685.html
聚焦vue3,但不限于vue,任何前端问题,究其本质,值得讨论,研究与学习。文章来源地址https://www.toymoban.com/news/detail-407685.html
到了这里,关于【vue3 之 emits & $emit() 讲解 】监听子组件事件、emit事件验证、options写法、composition setup写法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!