eozzy
eozzy

Reputation: 68720

Prevent event bubbling in Vue

<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.

Upvotes: 102

Views: 94353

Answers (5)

Mayank Kumar Chaudhari
Mayank Kumar Chaudhari

Reputation: 18656

I was creating a navigation bar and had similar requirements. I wanted the popup menu to be closed when clicked anywhere except on 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;
    })
}

Upvotes: 4

Phil
Phil

Reputation: 164924

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>

Upvotes: 77

Rameez Rami
Rameez Rami

Reputation: 5728

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>

Upvotes: 18

Ian
Ian

Reputation: 3676

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')
    }
  }
})

Upvotes: 4

omarjebari
omarjebari

Reputation: 5519

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>

Upvotes: 154

Related Questions