124

Is it possible to prevent the function on the <div> element from running when clicking the button inside the div?

When clicking the button element, the function: toggleSystemDetails should not be triggered? Is this possible in Vue?

<div v-on:click="toggleSystemDetails($event, system.id)" v-for="(system, index) in organization.systems" :key="system.id">
  Outer Div
  <button v-on:click="toggleTileOptionsMode($event, system.id, system.name, system.layout)">
    Inner Button
  </button>
</div>
Justin
  • 2,883
  • 1
  • 17
  • 25
hauge
  • 1,465
  • 4
  • 13
  • 20
  • Possible duplicate of [Section div closing handle z-index](https://stackoverflow.com/questions/45675436/section-div-closing-handle-z-index) – thanksd Aug 15 '17 at 20:04

6 Answers6

222

Have a look at Event Modifiers in the Vue.js v3 docs (v2 docs here), v-on:click.stop will stop that click from propagating or "bubbling" up to the parent element.

Justin
  • 2,883
  • 1
  • 17
  • 25
  • 9
    Think this is now actually `v-on:click.prevent` – PJATX Mar 20 '20 at 17:18
  • 8
    @PJATX that's another event modifier (and is covered in the VueJS guide I linked). Useful with form submit for instance if you want to prevent the browser from doing its default action. In this specific instance the stop modifier is better because the question is about stopping the click from propagating up the chain to the parent div. – Justin Mar 22 '20 at 22:47
  • Ah got it. I saw another post that gave the impression the above was the new syntax. I found this while trying to stop clicks on a child element from reaching the parent and `.stop` didn't work while `.prevent` did. Context was clicking on a modal vs modal background. – PJATX Mar 23 '20 at 21:12
  • I tried adding .stop but it would still resolve as soon as the next event fires... – leonheess Sep 18 '20 at 10:05
  • @PJATX are you possibly referring to Vue 3? ".stop" still works in Vue2, just tested it. – Armin May 23 '21 at 16:31
  • In my case I wanted to prevent click on the `tr` from a `table` when I clicking in an ' href` without a method. I used `.self` in the ' td` and moved the method from the `tr' to each `td`. Check it out: https://stackoverflow.com/questions/68838076/how-to-ignore-that-clicking-on-a-td-tag-does-not-automatically-redirect-me-to-an/74465289#74465289 – JotaPardo Nov 16 '22 at 18:13
93

Here is how to master this problem.

Say you have a parent element and some child elements.

1.(1st case) You want the parent click to do not affect the child clicks. Just put at the parent element the .self modifier:

  <div class="parent" @click.self="parent"> <!-- .self modifier -->
    <span class="child" @click="child1">Child1</span>
    <span class="child" @click="child2">Child2</span>
    <span class="child" @click="child3">Child3</span>
  </div>

See it in action here

note: if you remove the .self when you click a child, the parent event will fire too.

2.(2nd case) You have the below code:

  <div @click="parent">
    Click to activate 
    <i class="fa fa-trash" title="delete this" @click="delete_clicked"></i>
  </div>

The problem is:

  1. When you click the icon element the parent click will fire. (you don't want this)
  2. You can NOT use the 1st solution because you want to fire the parent event even if the text "Click to activate" gets clicked.

The solution to this is to put the .stop modifier to the icon element so the parent event will not fire.

See it in action here

Roland
  • 24,554
  • 4
  • 99
  • 97
  • 2
    Great answer - perhaps you could edit the answer to actually include the `@click.stop` in the sample code in the answer itself, not just in the linked code? – Dan Nissenbaum Aug 15 '21 at 14:39
16

as mentioned on the link provided by Justin you can .self in the click event

<!-- only trigger handler if event.target is the element itself -->
<!-- i.e. not from a child element -->
<div v-on:click.self="doThat">...</div>
tony19
  • 125,647
  • 18
  • 229
  • 307
Mawardy
  • 3,618
  • 2
  • 33
  • 37
11

I just want to put my two cents here, since I do find myself looking for this problem again and again (one day I will remember).

I have found in some instances, the child element needs @click.stop.prevent and that's it, to stop it from bubbling to the parent. I assume v-on:click.stop.prevent would have the same effect (non-shorthand).

Quin
  • 152
  • 3
  • 10
  • 1
    Nice. This also works great when the button is delivered by a component and the `@click` event is being handled in a parent view. – DaveL17 Oct 29 '21 at 18:38
7

additionally, if a child element detains you from clicking the parent element, you can fix this by adding CSS to the child element pointer-events: none. this solution is valid if there is no event in the child element.

M. Emre Yalçın
  • 608
  • 1
  • 7
  • 10
3

You can use @click.stop on child component, for examaple

.modal(@click="myfunc")
    default-content(@click.stop)