模板指令-v-on.native
v-on
的 .native
修饰符已被移除。
2.0 语法
默认情况下,传递给带有 v-on
的组件的事件监听器只能通过 this.$emit
触发。要将原生 DOM 监听器添加到子组件的根元素中,可以使用 .native
修饰符:
<my-component v-on:close="handleComponentEvent" v-on:click.native="handleNativeClickEvent" />
3.0 语法
v-on
的 .native
修饰符已被移除。同时,新增的 emits
选项允许子组件定义真正会被触发的事件。
因此,对于子组件中未被定义为组件触发的所有事件监听器,Vue 现在将把它们作为原生事件监听器添加到子组件的根元素中 (除非在子组件的选项中设置了 inheritAttrs: false
)。
vue3的组件选项中出现了一个新的选项Emits,它本身应该是一个数组,vue3中事件相关的api变化非常大,像一些事件的监听都会被移除掉,Emits主要是和组件的自定义事件有关,官方建议如果你的组件中有
自定义事件你需要使用Emits
迁移策略
- 删除.native修饰符的所有实例
- 确保所有组件都使用Emits选项记录其事件
app.vue
<template> <div> app <emit @click="onClick"></emit> </div> </template> <script> import emit from "./components/emit.vue" export default { components:{ emit }, setup(){ function onClick(){ console.log("emit"); } return {onClick} } } </script>
emit.vue
<template> <div @click="$emit('click')"> 自定义事件 </div> </template> <script> export default { } </script>
此时点击一下回触发两次
自定义事件和原生事件名称一样,而且自定义事件没有写入到emits中,就会出现以下问题,click事件会触发两次
Emits使用
emit.vue
<script>
export default {
emits:['click'] //仅对自定义事件做处理,原生事件不会被处理
}
</script>
此时点击之后就会触发一次
自定义事件名称和原生事件名称区分开也可以避免触发两次
app.vue
<template>
<div>
app
<emit @zclick="onClick"></emit>
</div>
</template>
<script>
import emit from "./components/emit.vue"
export default {
components:{
emit
},
setup(){
function onClick(){
console.log("emit");
}
return {onClick}
}
}
</script>
emit.vue
<template> <div @click="$emit('zclick')"> 自定义事件 </div> </template>
此时也会触发一次
对象形式的事件校验
与prop类型验证是类似,如果使用对象语法而不是数组语法定义发出的事件,则可以验证它
如果自定义事件是通过对象语法声明,那么这个自定义事件可以像prop校验一样进行验证,要添加验证,将为事件分配一个函数 函数会接收传递给$emit调用的参数,并返回一个布尔值来说明事件是否有效
案例:
app.vue
<template> <div> app <check @submit="sub"></check> </div> </template> <script> import check from "./components/check.vue" export default { components:{ check }, setup(){ function sub(e){ console.log(e,'e') //参数e接收的是表单元素里面的邮箱和密码 } return {sub} } } </script>
check.vue
<template> <div> 邮箱:<input type="text" v-model="email"> <br/> 密码: <input type="password " v-model="password"> <br/> <button @click="submitForm"> 提交</button> </div> </template> <script> import {ref} from "vue" export default { // 对象语法定义,可以进行验证 emits:{ //没有任何验证 //'click':null,
//要添加验证,将为事件分配一个函数 //函数会接收传递给$emit调用的参数,并返回一个布尔值,来说明事件是否有效 submit:({email,password})=>{ if(email&&password){ return true; }else{ console.warn('邮箱密码不能为空'); return false } } }, setup(props,ctx){ let email=ref('') let password=ref('') function submitForm(){ ctx.emit('submit',{email:email.value,password:password.value}) } return {email,password,submitForm } } } </script>
自定义事件验证无效
当我们什么也不输入就点击提交时就会弹出警告
有效的事件
当我们输入内容在点击提交之后就会输出我们输入的内容