Vue3:emits属性节点

2,236 阅读1分钟

Vue 3 现在提供一个 emits 选项,和现有的 props 选项类似。这个选项可以用来定义一个组件可以向其父组件触发的事件。

2.x

在 Vue 2 中,你可以定义一个组件可接收的 prop,但是你无法声明它可以触发哪些事件:

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

.native 修饰符

<template>
  <div class="app">
      <!-- native:事件修饰符,告诉系统这是一个原生事件,允许通过原生方式来触发 -->
      <child @ckick.native="handler"/>
  </div
</template>
<script>
new Vue({
    el:"#app",
    methods:{
        //click事件处理函数
        hanler:{
            console.log('触发click事件');
        }
    },
    components:{...}
});
</script>

3.x

  • 针对组件对象新增的属性节点
  • 告诉系统组件调用标签上添加的事件是一个自定义事件,需要通过自定义事件的方式进行触发(vue3中默认会将组件调用标签上的事件作为原生事件进行触发) 和 prop 类似,现在可以通过 emits 选项来定义组件可触发的事件:
<template>
  <div>
    <p>{{ text }}</p>
    <button v-on:click="$emit('accepted')">OK</button>
  </div>
</template>
<script>
  export default {
    props: ['text'],
    emits: ['accepted']
  }
</script>

该选项也可以接收一个对象,该对象允许开发者定义传入事件参数的验证器,和 props 定义里的验证器类似。

强烈建议使用 emits 记录每个组件所触发的所有事件,移除了 .native 修饰符。任何未在 emits 中声明的事件监听器都会被算入组件的 $attrs,并将默认绑定到组件的根节点上。

示例

对于向其父组件透传原生事件的组件来说,这会导致有两个事件被触发:

<template>
  <button v-on:click="$emit('click', $event)">OK</button>
</template>
<script>
export default {
  emits: [] // 不声明事件
}
</script>

当一个父级组件拥有 click 事件的监听器时:

<my-button v-on:click="handleClick"></my-button>

该事件现在会被触发两次:

  • 一次来自 $emit()
  • 另一次来自应用在根元素上的原生事件监听器。

现在你有两个选项:

  1. 正确地声明 click 事件。当你真的在 <my-button> 的事件处理器上加入了一些逻辑时,这会很有用。
  2. 移除透传的事件,因为现在父组件可以很容易地监听原生事件,而不需要添加 .native。适用于你只想透传这个事件