vue3 emits 自定义事件声明
在vue2的时候,我们的自定义事件是通过this.$emit
进行触发的,并没有统一的某一处属性进行定义,这其实会导致一个问题,当代码量上升一定程度后,后面来维护的人很难快速了解这个组件的自定义事件有哪些。
vue3版本提供了emits
配置,它可以定义当前组件触发的自定义事件有哪些,并且还支持参数校验,如果绑定的事件没有在emits
中显式声明,那么就会作为$attrs
属性挂载到根节点上,这个效果在fragment组件是无效的。
为此vue3放弃了.native
修饰符,一方面是因为emits的存在,可以更加明确的知道该组件支持什么自定义事件,另一方面是因为未声明的事件会默认绑定到根节点上,所以.native已经可有可无了,它的作用本身也是将事件绑定到组件的根节点上而已。
如果不想让未声明的事件会默认绑定到根节点上,可以给组件配置inheritAttrs: false
,关闭继承属性,这个功能在vue2中也存在,就不细说了。关键字:透传
普通用法
子组件
<template>
<button @click="onClick">aaa</button>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
emits: ["click"],
setup(props, { emit }) {
function onClick() {
emit("click", "test");
}
return {
onClick,
};
},
});
</script>
父组件
<template>
<div>
<test @click="onClick" />
</div>
</template>
<script lang="ts">
import { defineComponent } from "vue";
import test from "./components/test.vue";
export default defineComponent({
setup() {
function onClick(val: string) {
console.log(val);
}
return {
onClick,
};
},
components: {
test,
},
});
</script>
使用上出来emit是通过setup参数获取之外,其他并没有什么不同。
注意
如果子组件没有在emits
中声明click事件,那么当我们点击btn按钮的时候,click会触发两次,所以一定要注意,自定义事件一定要在emits
中声明。
这两次事件分别是由:
- emit触发
- 子组件根元素的click事件
而且我们不推荐emits中使用原生事件的名称,建议是自己编一个事件名,比如:myClick
当然,这个触发两次在vue2中并不会出现。
参数校验
从官方的类型定义上看
interface ComponentOptions {
emits?: ArrayEmitsOptions | ObjectEmitsOptions
}
type ArrayEmitsOptions = string[]
type ObjectEmitsOptions = { [key: string]: EmitValidator | null }
type EmitValidator = (...args: unknown[]) => boolean
使用数组,那么事件名全都是string类型,如果使用键值对,那么就可以声明一个校验函数,来进行参数校验,这个校验函数接的参就是我们emit
触发时传的参,当我们校验后返回一个布尔值,如果不return布尔值,那么默认是undefined
,转为布尔值就是false,所以这个需要注意。
目前这个参数校验并不会阻断我们的事件触发,当校验函数返回的是false的时候,也仅仅是在控制台输出一段警告,我们也可以自己手动打印一个警告,虽然官方推荐使用,但是好似没有太大的功能性提升,如果能阻断事件,我觉得会是一个很好的功能,但是目前没有这么做。
所以,目前数组形式的emits是常见的做法。
<template>
<button @click="onClick">aaa</button>
</template>
<script lang="ts">
import { defineComponent } from "vue";
export default defineComponent({
emits: {
click: (val: string) => {
if (val !== "test") {
return false;
}
return true;
},
},
setup(props, { emit }) {
function onClick() {
emit("click", "test");
}
return {
onClick,
};
},
});
</script>
本文系作者 @木灵鱼儿 原创发布在木灵鱼儿站点。未经许可,禁止转载。
暂无评论数据