前言

本笔记主要基于官方文档《迁移策略—— emits 选项》汇总而来。如有理解出入,请以官方文档为主。建议您以官方文档为主,本文为辅。这样您可以“以自己为主”审视的阅读,从而不被我的观点带偏。

概述

Vue 3.x 新增了一个emits 组件选项,用来定义组件可以向父组件 emit 的事件。其类似于 props

Vue 2.x 的 emit

在 Vue 2.x , 我们可以定义组件接收的props,但是我们不能声明组件可以emit哪些event

<template>
  <div>
    <p>{{ text }}</p>
    <button v-on:click="$emit('accepted')">OK</button>
  </div>
</template>
<script>
  export default {
    props: ['text']
  }
</script>

Vue 3.x 的 emit

到了 Vue 3.x ,组件所有 emit 的事件必须要在emits 选项中声明。

<template>
  <div>
    <p>{{ text }}</p>
    <button v-on:click="$emit('accepted')">OK</button>
  </div>
</template>
<script>
  export default {
    props: ['text'],
    emits: ['accepted']
  }
</script>

此外,emits 可以接收一个对象。每个属性的值可以为空,也可以为验证器函数。

<template>
  <div>
    <p>{{ text }}</p>
    <button v-on:click="$emit('click')">click</button>
    <button v-on:click="$emit('submit')">submit</button>
  </div>
</template>
<script>
  export default {
    props: ['text'],
    emits: {
    // no validation
    click: null,

    // with validation
    submit: payload => {
      if (payload.email && payload.password) {
        return true
      } else {
        console.warn(`Invalid submit event payload!`)
        return false
      }
    }
  }
  }
</script>

强烈建议组件中使用的所有通过emit触发的event都在emits中声明。

因为Vue 3.x 中移除的.native修饰符。任何没有在emits中进行声明的event,将会自动被添加到$attrs。而attrs默认情况下是绑定到根组件的。

英文原文:

It is highly recommended that you document all of the events emitted by each of your components using emits.

This is especially important because of the removal of the .native modifier. Any listeners for events that aren’t declared with emits will now be included in the component’s $attrs, which by default will be bound to the component’s root node.

这样就会造成,如果emit的是原生的事件(如,click),就会存在两次触发。如:

<template>
  <button v-on:click="$emit('click', $event)">OK</button>
</template>
<script>
export default {
  emits: [] // without declared event
}
</script>
  • 一次来自于$emit的触发;

  • 一次来自于根元素原生事件监听器的触发;


本系列目录

Logo

前往低代码交流专区

更多推荐