message: feat(@vant/use): support cleanup useEventListener
diff: -import { Ref, watch, isRef, unref, onUnmounted, onDeactivated } from 'vue';
  +import {
  + Ref,
  + watch,
  + isRef,
  + unref,
  + onUnmounted,
  + onDeactivated,
  + type WatchStopHandle,
  +} from 'vue';
  import { onMountedOrActivated } from '../onMountedOrActivated';
  import { inBrowser } from '../utils';
  @@ -14,12 +22,12 @@ export function useEventListener<K extends keyof DocumentEventMap>(
  type: K,
  listener: (event: DocumentEventMap[K]) => void,
  options?: UseEventListenerOptions
  -): void;
  +): () => void;
  export function useEventListener(
  type: string,
  listener: EventListener,
  options?: UseEventListenerOptions
  -): void;
  +): () => void;
  export function useEventListener(
  type: string,
  listener: EventListener,
  @@ -31,9 +39,13 @@ export function useEventListener(
  const { target = window, passive = false, capture = false } = options;
  + let cleaned = false;
  let attached: boolean;
  const add = (target?: TargetRef) => {
  + if (cleaned) {
  + return;
  + }
  const element = unref(target);
  if (element && !attached) {
  @@ -46,6 +58,9 @@ export function useEventListener(
  };
  const remove = (target?: TargetRef) => {
  + if (cleaned) {
  + return;
  + }
  const element = unref(target);
  if (element && attached) {
  @@ -58,10 +73,21 @@ export function useEventListener(
  onDeactivated(() => remove(target));
  onMountedOrActivated(() => add(target));
  + let stopWatch: WatchStopHandle;
  +
  if (isRef(target)) {
  - watch(target, (val, oldVal) => {
  + stopWatch = watch(target, (val, oldVal) => {
  remove(oldVal);
  add(val);
  });
  }
  +
  + /**
  + * Clean up the event listener
  + */
  + return () => {
  + stopWatch?.();
  + remove(target);
  + cleaned = true;
  + };
  }
  