模板指令-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>

 自定义事件验证无效

当我们什么也不输入就点击提交时就会弹出警告

 

有效的事件

当我们输入内容在点击提交之后就会输出我们输入的内容

 

 

posted @ 2021-11-11 13:26  keyeking  阅读(649)  评论(0编辑  收藏  举报