Skip to content

20 - 节流点击指令 #3117

@PosionEdgar

Description

@PosionEdgar
<script setup lang='ts'>

/**
 * Implement the custom directive
 * Make sure the `onClick` method only gets triggered once when clicked many times quickly
 * And you also need to support the debounce delay time option. e.g `v-debounce-click:ms`
 *
*/

import { DirectiveBinding, ref } from 'vue';

const debounce = (fn, wait, immediate = false) => {
  let timer = null;
  return function (...args) {
    const context = this;
    if (timer) {
      clearTimeout(timer)
      timer = null
    }
    if (immediate && wait === 0) {
      fn.apply(context, args)
    } else {
      timer = setTimeout(() => {
        fn.apply(context, args)
        clearTimeout(timer)
        timer = null
      }, wait)
    }
  }
}

let debounceFn;
const VDebounceClick = {
  mounted: (el: HTMLElement, binding: DirectiveBinding) => {
    const { value: cb, arg: delay } = binding;
    debounceFn = debounce(cb, delay)
    el.addEventListener('click', debounceFn)
  },
  onunmounted: (el: HTMLElement) => {
    el.removeEventListener('click', debounceFn)
  }
}

const count = ref(0)
function onClick() {
  count.value ++
  console.log("Only triggered once when clicked many times quickly")
}

</script>

<template>
  <button v-debounce-click:200="onClick">
    Click on it many times quickly {{ count }}
  </button>
</template>

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions