vuejs-challenges
vuejs-challenges copied to clipboard
20 - 节流点击指令
// 你的答案
<script setup lang='ts'>
import { DirectiveBinding } from 'vue'
/**
* 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`
*
*/
interface Callback {
(): void
}
function Debounce<T extends Callback>(fn: T, delay: number, immediate: boolean ): T {
let timer = null
return function () {
const context = this,
args = arguments;
if (timer) clearTimeout(timer);
if (immediate) {
const execute = !timer;
setTimeout(() => {
timer = null;
}, delay);
if (execute) fn.apply(context, args)
} else {
timer = setTimeout(() => {
fn.apply(context, args)
}, delay)
}
}
}
const VDebounceClick = {
mounted(el: HTMLButtonElement, binding: DirectiveBinding) {
const { arg, value } = binding
el.addEventListener('click', Debounce(value, arg), false)
}
}
function onClick() {
console.log("Only triggered once when clicked many times quickly")
}
</script>
<template>
<button v-debounce-click:2000="onClick">
Click on it many times quickly
</button>
</template>