Vue js how to prevent button clicked on two times continuously [duplicate]
Asked Answered
J

2

9

I have a button, user can click the button more than one time if he want. But when the user click the button, he might accidentally click twice, in such cases second click should be blocked by the code.

If I further explain. They should be a small delay between two clicks.

How do I achieve this using vue js?

In Vue docs Event modifiers I found .stop

<button @click.stop="myFunction">Increase</button>

Does this do the job what I want?

Jetta answered 13/2, 2019 at 4:4 Comment(3)
No click.stop will just stop your event from propagating to parent elements.Claustral
you can add disabled attribute to the button once the button is clicked. then remove the disabled attribute once the logic is done.Histogen
How about disabling the button for some time until the myFunction is executed using setTimeout?Here is the fiddle to check jsfiddle.net/vitragparekh/9k76oh23/6Claustral
D
11

No, the .stop modifier does not solve your problem. What that modifier does is to prevent event propagation (it is equivalent to stopPropagation() in plan JavaScript)

You could use the .once modifier to prevent any further events after the first one. However, if you want to allow multiple clicks, but have a delay between them, you could do something like this:

<template>
    <button :disabled="disabled" @click="delay">Increase</button>
</template>

<script>
  export default {
    data () {
      return {
        disabled: false,
        timeout: null
      }
    },
    methods: {
      delay () {
        this.disabled = true

        // Re-enable after 5 seconds
        this.timeout = setTimeout(() => {
          this.disabled = false
        }, 5000)

        this.myFunction()
      },
      myFunction () {
        // Your function
      }
    },
    beforeDestroy () {
     // clear the timeout before the component is destroyed
     clearTimeout(this.timeout)
    }
  }
</script>
Dolomite answered 13/2, 2019 at 4:19 Comment(0)
B
4

As others have said the .stop modifier will only stop the event from propagating up the DOM. To achieve the result you're looking for you could look into Lodash's debounce method ..

_.debounce(func, [wait=0], [options={}])

Creates a debounced function that delays invoking func until after wait milliseconds have elapsed since the last time the debounced function was invoked.

Here's a simple example ..

new Vue({
  el: "#app",
  data: {
    counter: 0
  },
  methods: {
    myFunction() {
      this.counter++
    },
  },
  created() {
    this.debouncedMyFunction = debounce(this.myFunction, 300, {
      leading: true,
      trailing: false
    })
  }
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.4/vue.min.js"></script>
<script src="https://unpkg.com/[email protected]/index.js"></script>

<div id="app">
  <button @click.stop="debouncedMyFunction">Increase</button>
  <p>
    {{ counter }}
  </p>
</div>

Specifying the leading option to true and trailing to false will cause the function to be invoked on the leading edge of the timeout instead of the trailing end. You can change the timeout value from 300 to your desired value in milliseconds.

Balk answered 13/2, 2019 at 4:34 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.