javascript 停止自定义事件传播到Vue 3中的根组件

rdlzhqv9  于 2023-04-19  发布在  Java
关注(0)|答案(2)|浏览(137)

我创建了几个使用自定义事件相互通信的组件。
问题是我在事件传播方面遇到了困难。我有一个App.vue组件,它示例化了一个GeneriqueButton组件,而GeneriqueButton组件又示例化了一个BaseButton组件。我已经在GeneriqueButton上添加了一个带有.stop修饰符的事件侦听器,以防止事件传播到App.vue,但事件仍然冒泡到App.vue,我在控制台中发送了消息。
我不明白为什么尽管使用了.stop修饰符,事件仍然继续传播。我已经验证了事件是从BaseButton发出的,但它仍然被App.vue捕获。
下面是三个组件的代码:
App.vue:

<template>
  <GeneriqueButton @base-button="printConsole"/>
</template>

<script setup>
import GeneriqueButton from './GeneriqueButton.vue'
function printConsole(event) {
  console.log('App.vue : BaseButton clicked !', event)
}
</script>

GeneriqueButton.vue

<template>
  <BaseButton @base-button.stop="printConsole" />
</template>

<script setup>
import BaseButton from './BaseButton.vue'
function printConsole(event) {
  console.log('GeneriqueButton.vue : BaseButton clicked !', event)
}
</script>

BaseButton.vue

<template>
  <button type="button" @click="$emit('base-button', $event)">
    Click me
  </button>
</template>

我在App.vue和GeneriqueButton.vue中使用console.log,每次单击按钮,我的控制台中有2个日志:



你知道是什么导致了这个事件传播问题吗?你有什么建议来解决它吗?
提前感谢您的帮助。

ukdjmx9f

ukdjmx9f1#

这看起来很奇怪,但实际上并不是自定义事件冒泡,而是侦听器向下传播。
以下是发生的情况:

  • 您的App.vue在GeneriqueButton按钮组件上设置了一个事件侦听器
  • GeneriqueButton并不以该名称声明事件,因此侦听器被添加到fallthrough attributes(组件的attr对象)
  • 因为GeneriqueButton只有一个根元素,所以attrs被传递到根节点,包括监听器
  • GeneriqueButton还为同一事件在BaseButton上添加了另一个事件侦听器
  • BaseButton发出(未声明的)事件,并调用两个侦听器

请注意,.stop将停止本地事件的事件传播,您可以在按钮上的@click上使用它来停止单击事件冒泡。它不适用于自定义事件,这些事件根本不冒泡。
以下是你可以做的来避免这种情况:

  • 不要在App.vue上设置事件处理程序,除非您明确希望将其传递给嵌套的单个根元素
  • 使GeneriqueButton成为非单根元素
  • 按照@TazHinkle的建议,禁用GeneriqueButton上的fallthrough属性
osh3o9ms

osh3o9ms2#

根据Vue3.JS的文档,自定义事件不福尔斯默认的事件冒泡,就像原生事件一样。
与原生DOM事件不同,组件发出的事件不会冒泡。您只能监听直接子组件发出的事件。如果需要在同级或深度嵌套组件之间进行通信,请使用外部事件总线或全局状态管理方案。

相关问题