[Vuejs]-How to make parent ignore the event coming from child

0👍

Assuming you also need to keep the @click handler on the parent element, one potential solution is to use the .self modifier:

<template>
  <div class="hello" @click.self="openAlert">
    <div class="hello_title">{{ title }}</div>
    <!-- Within the dropdown component is another @click handler -->
    <dropdown class="hello_dropdown" :dropdownId="id" />
  </div>
</template>

There is a caveat with this approach: the event will not trigger on clicks of any child. In your example (and the snippet above), clicks on the div with class hello_title will not trigger the openAlert handler.

With a simple DOM tree, this limitation might be easy to work around. Simply add separate handlers to each descendant (you can omit the .self assuming the dropdown component is not a child in those descendant DOM subtrees). However, that strategy might not be desirable if your component hierarchy is complicated.


If a more robust solution is needed, consider creating a separate "Event Bus" Javascript module that can be imported and used by multiple components. In its simplest form, it could be a wrapper around a map of strings to handler functions:

const map = {};

export function addEventListener(name, fn) {
  if (!map[name]) map[name] = [];
  map[name].push(fn);
}

export function emit(name, ...args) {
  if (map[name]?.length) {
    for (const fn of map[name]) {
      fn(...args);
    }
  }
}

Your dropdown components can register their listeners on the event bus (rather than the document body), and they can also emit to the bus appropriate events from a handler whose propagation is stopped (since you no longer need to let the event bubble up to the document body). At that point, the parent div could just use the standard, unmodified @click syntax, because clicks on the dropdown would be ignored.

<template>
  <div class="hello" @click="openAlert">
    <div class="hello_title">{{ title }}</div>
    <!-- Within the dropdown component is a @click.stop handler, delegating to the event bus -->
    <dropdown class="hello_dropdown" :dropdownId="id" />
  </div>
</template>

Leave a comment