diff --git a/packages/vant-use/src/index.ts b/packages/vant-use/src/index.ts
index 320c57177..50c6f6900 100644
--- a/packages/vant-use/src/index.ts
+++ b/packages/vant-use/src/index.ts
@@ -1 +1,2 @@
 export { useToggle } from './useToggle';
+export { useEventListener } from './useEventListener';
diff --git a/packages/vant-use/src/useEventListener/index.ts b/packages/vant-use/src/useEventListener/index.ts
new file mode 100644
index 000000000..9a380589b
--- /dev/null
+++ b/packages/vant-use/src/useEventListener/index.ts
@@ -0,0 +1,69 @@
+import {
+  Ref,
+  unref,
+  onMounted,
+  onActivated,
+  onUnmounted,
+  onDeactivated,
+} from 'vue';
+
+const inBrowser = typeof window !== 'undefined';
+
+let supportsPassive = false;
+if (inBrowser) {
+  try {
+    const opts = {};
+    Object.defineProperty(opts, 'passive', {
+      get() {
+        supportsPassive = true;
+      },
+    });
+    window.addEventListener('test-passive', null as any, opts);
+    // eslint-disable-next-line no-empty
+  } catch (e) {}
+}
+
+export type UseEventListenerOptions = {
+  type: string;
+  target: EventTarget | Ref<EventTarget>;
+  capture?: boolean;
+  passive?: boolean;
+  listener: EventListener;
+};
+
+export function useEventListener({
+  type,
+  target,
+  passive = false,
+  capture = false,
+  listener,
+}: UseEventListenerOptions) {
+  let attached: boolean;
+
+  const add = () => {
+    const element = unref(target);
+
+    if (element && inBrowser && !attached) {
+      element.addEventListener(
+        type,
+        listener,
+        supportsPassive ? { capture, passive } : capture
+      );
+      attached = true;
+    }
+  };
+
+  const remove = () => {
+    const element = unref(target);
+
+    if (element && inBrowser && attached) {
+      element.removeEventListener(type, listener, capture);
+      attached = false;
+    }
+  };
+
+  onMounted(add);
+  onActivated(add);
+  onUnmounted(remove);
+  onDeactivated(remove);
+}
diff --git a/packages/vant-use/tsconfig.json b/packages/vant-use/tsconfig.json
index 6d9136383..60581a788 100644
--- a/packages/vant-use/tsconfig.json
+++ b/packages/vant-use/tsconfig.json
@@ -7,8 +7,7 @@
     "declaration": true,
     "skipLibCheck": true,
     "esModuleInterop": true,
-    "moduleResolution": "Node",
-    "lib": ["esnext"]
+    "moduleResolution": "Node"
   },
   "include": ["src/**/*"]
 }