8

I am trying to create a reusable debounce function in Vue 3 using the composition API but am struggling to get it to work.

This is what I have so far:

debounce.js

const debounce = (fn, delay) => {
  let timeout

  return (...args) => {
    if (timeout) {
      clearTimeout(timeout)
    }

    timeout = setTimeout(() => {
      fn(...args)
    }, delay)
  }
}

export default debounce

BaseComponent.vue

<template>
  <input type="text" @input="onInput" />
</template>

<script>
import debounce from './debounce'

export default {
  setup() {
    const onInput = () => {
      debounce(() => {
        console.log('debug')
      }, 500)
    }

    return { onInput }
  }
}
</script>

The callback passed to the debounce function is not being triggered. I'm not seeing the output in the console.

Dan
  • 59,490
  • 13
  • 101
  • 110
imot3k
  • 95
  • 1
  • 2
  • 5

1 Answers1

9

The debounce function you have is a higher-order function which generates and returns a new function. That generated function is the one that should be used as an event handler to implement the debouncing behavior that you want.

Call debounce only once, and set that generated debouncer function to be used as the event handler:

setup() {
  const onInput = debounce(() => {
    console.log('debug')
  }, 500)
  return { onInput }
}

Otherwise, the handler calls debounce again each time it's triggered, and generates a new debouncer function each time, with no relation to the last one.

Dan
  • 59,490
  • 13
  • 101
  • 110