Prevent event bubbling in Vue

vue.jsClickEvent BubblingEvent Propagation

vue.js Problem Overview


<div id="largeArea" v-on:click="do_X">
    <button>Button</button>
</div>

So I have this issue in Vue where I don't want "do_X" to trigger when I click on the button, although its a part of the largeArea.

vue.js Solutions


Solution 1 - vue.js

I found that using the 'stop' event modifier on the child element worked for me. eg

<div id="app">
  <div id="largeArea" @click="do_X">
    <button @click.stop="do_Y">Button</button>
  </div>
</div>

Solution 2 - vue.js

From the documentation, use the self event modifier to only capture events originating on the element itself.

<div id="largeArea" v-on:click.self="do_X">

new Vue({
  el: '#app',
  methods: {
    do_X () {
      console.log(Date.now(), 'do_X')
    }
  }
})

#largeArea {
  padding: 20px;
  border: 1px solid black;
}

<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<div id="app">
  <div id="largeArea" @click.self="do_X">
    <button>Button</button>
  </div>
</div>

Solution 3 - vue.js

Prevent bubbling for all clicks inside a container <div>

<div @click.stop="" class="action">

  <button @click="someClickAction1()">Action 1</button>

  <button @click="someClickAction2()">Action 2</button>

<div>

Prevent bubbling on an existing click action

<button @click.stop="someClickAction()">Single Action</button>

Solution 4 - vue.js

Neither of the provided answers. In my situation it's wrapped in a <router-link> not a <div>.

I called e.preventDefault() on the child element and it worked

<router-link>
    <div @click="do_X"></div>
</router-link>

new Vue({
  el: '#app',
  methods: {
    do_X (e) {
    e.preventDefault();
      console.log(Date.now(), 'do_X')
    }
  }
})

Solution 5 - vue.js

I was creating a navigation bar and had similar requirements. I want the popup menu to be closed when clicked anywhere accept the menu or its children.

This can be done by using event modifiers. Fore reference see this docs

Specifically, we can use stop event modifier.

<div id="largeArea" v-on:click="do_X()">
    <button @click.stop="">Button</button>
</div>

.stop will stop the event propagation.


In my case better solution was to use e.target != this.$el

mounted() {
    window.addEventListener('click', (e)=>{
        if(e.target !== this.$el)
            this.showChild = false;
    })
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestioneozzyView Question on Stackoverflow
Solution 1 - vue.jsomarjebariView Answer on Stackoverflow
Solution 2 - vue.jsPhilView Answer on Stackoverflow
Solution 3 - vue.jsRameez RamiView Answer on Stackoverflow
Solution 4 - vue.jsIanView Answer on Stackoverflow
Solution 5 - vue.jsmayank1513View Answer on Stackoverflow