Vue3 emits Option 的作用与注意事项

972 阅读1分钟

1. Vue3

1.1 .native 修饰符

Vue3 中去掉了 .native 修饰符,默认给子组件的根元素上绑定了监听器。

1.2 emits Option

新增的 emits 允许子组件定义真正被触发的自定义事件。任何没有通过 emits 声明的事件监听器都会被挂载到组件的 $attrs 属性,因此也会被默认绑定到子组件的根节点。

1.3 代码演示

<!-- 父组件 -->
<template>
    <Child @click="onClick" />
</template>

<script>
export default {
    setup () {
        const onClick = (e) => console.log(`target: ${e.target.className};`, `currentTarget: ${e.currentTarget.className};`);
        return {
            onClick
        }
    }    
}
</script>
<!-- 子组件 -->
<template>
    <div class="emit-demo-child">
        <div class="div--click" @click="$emit('click', $event)">点击我</div>
    </div>
</template>

<script>
export default {
  emits: [] // 未声明自定义事件
}
</script>

CleanShot 2022-05-23 at 15.15.23.png

1.3.1 「现象」一次点击触发两次事件

  • 一次来自 $emit()
  • 一次来自子组件根元素的事件监听器。

1.3.2 解决方法

  1. 如果在子组件的事件处理中包含逻辑,可以在 emits 中声明 click 事件,从而只触发自定义事件。
  2. 如果在子组件的事件处理中不包含逻辑,可以移除 $emit(),因为子组件的根节点已经默认绑定了事件监听器。

2. Vue2

2.1 v-on 监听

对子组件使用 v-on,只会监听自定义事件(子组件内用 $emit 触发的事件)

2.2 .native 修饰符

  • 如果需要监听子组件根元素的原生事件,使用 .native 修饰符。
  • 子组件中,DOM 元素触发的事件会冒泡到根元素上。
  • .native 有自己的局限性,比如子组件的根节点由 input 变为 label 时,像@input.native="xxx" 等原生事件就会失效。此时为了兼容性需要做 $attr$listeners 的透传。具体参考 Vue2 文档#将原生事件绑定到组件

2.3 代码演示

<!-- 父组件 -->
<template>
    <Child @input.native="onInput" />
</template>

<script>
export default {
    methods: {
        onInput (e) {
            console.log(`target: ${e.target.className};`, `currentTarget: ${e.currentTarget.className};`);
        }
    }
}

</script>
<!-- 子组件 -->
<div class="emit-demo-child">
    <input id="input1" />
    <input id="input2" />
</div>

CleanShot 2022-05-23 at 15.10.50.png

「End」参考文档