MST

星途 面试题库

面试题:Vue复杂嵌套组件下的事件冒泡与捕获处理

假设有一个多层嵌套的Vue组件结构,父组件A包含子组件B,子组件B又包含子组件C。在子组件C的一个按钮点击事件中,希望在捕获阶段和冒泡阶段分别执行不同的逻辑,并且要在特定条件下阻止事件冒泡到父组件A,你会如何实现?请给出具体的代码结构和逻辑。
47.6万 热度难度
前端开发Vue

知识考点

AI 面试

面试题答案

一键面试
  1. HTML 结构 (App.vue)
<template>
  <div id="app">
    <ComponentA />
  </div>
</template>

<script setup>
import ComponentA from './components/ComponentA.vue';
</script>

<style>
#app {
  font-family: Avenir, Helvetica, Arial, sans-serif;
  -webkit - font - smoothing: antialiased;
  -moz - osx - font - smoothing: grayscale;
  text - align: center;
  color: #2c3e50;
  margin - top: 60px;
}
</style>
  1. 父组件 ComponentA.vue
<template>
  <div class="parent - a">
    <p>这是父组件 A</p>
    <ComponentB @my - custom - event.capture="handleCaptureInA" @my - custom - event="handleBubbleInA"/>
  </div>
</template>

<script setup>
import ComponentB from './ComponentB.vue';

const handleCaptureInA = () => {
  console.log('在父组件 A 的捕获阶段触发');
};

const handleBubbleInA = () => {
  console.log('在父组件 A 的冒泡阶段触发');
};
</script>

<style scoped>
.parent - a {
  border: 1px solid red;
  padding: 10px;
}
</style>
  1. 子组件 ComponentB.vue
<template>
  <div class="parent - b">
    <p>这是子组件 B</p>
    <ComponentC @my - custom - event.capture="handleCaptureInB" @my - custom - event="handleBubbleInB"/>
  </div>
</template>

<script setup>
import ComponentC from './ComponentC.vue';

const handleCaptureInB = () => {
  console.log('在子组件 B 的捕获阶段触发');
};

const handleBubbleInB = () => {
  console.log('在子组件 B 的冒泡阶段触发');
};
</script>

<style scoped>
.parent - b {
  border: 1px solid blue;
  padding: 10px;
}
</style>
  1. 子组件 ComponentC.vue
<template>
  <div class="child - c">
    <p>这是子组件 C</p>
    <button @click.capture="handleCaptureInC" @click="handleBubbleInC">点击我</button>
  </div>
</template>

<script setup>
const handleCaptureInC = () => {
  console.log('在子组件 C 的捕获阶段触发');
  // 可以在这里执行捕获阶段逻辑
};

const handleBubbleInC = () => {
  const shouldPreventBubble = true; // 特定条件
  console.log('在子组件 C 的冒泡阶段触发');
  if (shouldPreventBubble) {
    const event = new CustomEvent('my - custom - event', { cancelable: true });
    event.preventDefault();
    this.$emit('my - custom - event', event);
  } else {
    this.$emit('my - custom - event');
  }
};
</script>

<style scoped>
.child - c {
  border: 1px solid green;
  padding: 10px;
}
</style>

上述代码中,通过在 @click 修饰符后添加 .capture 来分别监听捕获阶段和冒泡阶段的点击事件。在子组件 ComponentC 的冒泡阶段逻辑中,根据 shouldPreventBubble 条件决定是否阻止事件冒泡,通过 event.preventDefault() 来阻止事件冒泡,并通过 $emit 触发自定义事件,传递带有 cancelable 属性的自定义事件对象,以便在父组件中能够捕获并处理是否阻止冒泡的情况。