index.ts 2.1 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768
  1. import {
  2. isArray,
  3. throttle,
  4. debounce,
  5. isObject,
  6. isFunction
  7. } from "@pureadmin/utils";
  8. import { useEventListener } from "@vueuse/core";
  9. import type { Directive, DirectiveBinding } from "vue";
  10. export interface OptimizeOptions {
  11. /** 事件名 */
  12. event: string;
  13. /** 事件触发的方法 */
  14. fn: (...params: any) => any;
  15. /** 是否立即执行 */
  16. immediate?: boolean;
  17. /** 防抖或节流的延迟时间(防抖默认:`200`毫秒、节流默认:`1000`毫秒) */
  18. timeout?: number;
  19. /** 传递的参数 */
  20. params?: any;
  21. }
  22. /** 防抖(v-optimize或v-optimize:debounce)、节流(v-optimize:throttle)指令 */
  23. export const optimize: Directive = {
  24. mounted(el: HTMLElement, binding: DirectiveBinding<OptimizeOptions>) {
  25. const { value } = binding;
  26. const optimizeType = binding.arg ?? "debounce";
  27. const type = ["debounce", "throttle"].find(t => t === optimizeType);
  28. if (type) {
  29. if (value && value.event && isFunction(value.fn)) {
  30. let params = value?.params;
  31. if (params) {
  32. if (isArray(params) || isObject(params)) {
  33. params = isObject(params) ? Array.of(params) : params;
  34. } else {
  35. throw new Error(
  36. "[Directive: optimize]: `params` must be an array or object"
  37. );
  38. }
  39. }
  40. // Register using addEventListener on mounted, and removeEventListener automatically on unmounted
  41. useEventListener(
  42. el,
  43. value.event,
  44. type === "debounce"
  45. ? debounce(
  46. params ? () => value.fn(...params) : value.fn,
  47. value?.timeout ?? 200,
  48. value?.immediate ?? false
  49. )
  50. : throttle(
  51. params ? () => value.fn(...params) : value.fn,
  52. value?.timeout ?? 1000
  53. )
  54. );
  55. } else {
  56. throw new Error(
  57. "[Directive: optimize]: `event` and `fn` are required, and `fn` must be a function"
  58. );
  59. }
  60. } else {
  61. throw new Error(
  62. "[Directive: optimize]: only `debounce` and `throttle` are supported"
  63. );
  64. }
  65. }
  66. };