ny
昨天 282fbc6488f4e8ceb5fda759f963ee88fbf7b999
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
import type { Ref } from 'vue';
 
import { ref, unref, watch } from 'vue';
 
import { useDebounceFn, useThrottleFn } from '@vueuse/core';
 
export type RemoveEventFn = () => void;
export interface UseEventParams {
  autoRemove?: boolean;
  el?: any | Element | Ref<Element | undefined> | Window;
  isDebounce?: boolean;
  listener: EventListener;
  name: string;
  options?: AddEventListenerOptions | boolean;
  wait?: number;
}
export function useEventListener({
  autoRemove = true,
  el = window,
  isDebounce = true,
  name,
  options,
  wait = 80,
  listener,
}: UseEventParams): { removeEvent: RemoveEventFn } {
  let remove: RemoveEventFn = () => {};
  const isAddRef = ref(false);
 
  if (el) {
    const element = ref(el as Element) as Ref<Element>;
 
    const handler = isDebounce
      ? useDebounceFn(listener, wait)
      : useThrottleFn(listener, wait);
    const realHandler = wait ? handler : listener;
    const removeEventListener = (e: Element) => {
      isAddRef.value = true;
      e.removeEventListener(name, realHandler, options);
    };
    const addEventListener = (e: Element) =>
      e.addEventListener(name, realHandler, options);
 
    const removeWatch = watch(
      element,
      (v, _ov, cleanUp) => {
        if (v) {
          !unref(isAddRef) && addEventListener(v);
          cleanUp(() => {
            autoRemove && removeEventListener(v);
          });
        }
      },
      { immediate: true },
    );
 
    remove = () => {
      removeEventListener(element.value);
      removeWatch();
    };
  }
  return { removeEvent: remove };
}