当前位置: 首页 > news >正文

React vs Vue:点击外部事件处理的对比与实现

React vs Vue:点击外部事件处理的对比与实现

在 Web 应用中,“点击外部事件监听”是一种常见需求,典型应用如:点击弹窗外部关闭弹窗、点击下拉菜单外关闭菜单。虽然在 React 和 Vue 中实现的原理类似——都是通过监听 document 的点击事件并判断点击是否在目标元素外,但在两者框架中的编码方式和理念却有所不同。


📦 原理一致:判断是否点击在目标元素外

无论使用 Vue 还是 React,核心逻辑都是:

function isClickOutside(el: HTMLElement, target: EventTarget | null) {return el && target && !el.contains(target as Node)
}

这段逻辑判断点击的目标是否在 el 外部。


🔷 React 实现方式:使用 Hook

React 倾向于函数式和组合式思维,处理副作用的方式是通过 useEffect() 来注册和销毁事件。

import { useEffect, RefObject } from 'react'export function useClickOutside(ref: RefObject<HTMLElement>, handler: (e: MouseEvent) => void) {useEffect(() => {const listener = (e: MouseEvent) => {if (!ref.current || !isClickOutside(ref.current, e.target)) returnhandler(e)}document.addEventListener('mousedown', listener)return () => document.removeEventListener('mousedown', listener)}, [ref, handler])
}

使用方式

const ref = useRef(null)
useClickOutside(ref, () => console.log('clicked outside'))
  • ✅ 基于组件级 Hook
  • ✅ 支持函数依赖管理
  • ✅ 可按需组合并复用

🔶 Vue 实现方式:组合式 API + 自定义指令

Vue 提供两种实现路径:组合式 API(Composition API)和自定义指令(Directives)。

方法一:组合式 API

import { onMounted, onBeforeUnmount } from 'vue'export function useClickOutsideVue(elGetter: () => HTMLElement | null, handler: (e: MouseEvent) => void) {const listener = (e: MouseEvent) => {const el = elGetter()if (!el || !isClickOutside(el, e.target)) returnhandler(e)}onMounted(() => document.addEventListener('click', listener))onBeforeUnmount(() => document.removeEventListener('click', listener))
}

方法二:自定义指令

export const vClickOutside = {mounted(el: HTMLElement, binding: any) {el.__ClickOutside__ = (e: MouseEvent) => {if (isClickOutside(el, e.target)) {binding.value(e)}}document.addEventListener('click', el.__ClickOutside__)},unmounted(el: HTMLElement) {document.removeEventListener('click', el.__ClickOutside__)}
}

使用方式

<template><div v-click-outside="onClose">弹窗</div>
</template>
  • ✅ 更贴合模板语法
  • ✅ 易于在 UI 层应用
  • ✅ 可复用在多个 DOM 元素上

🔍 对比总结

对比项ReactVue
使用方式Hook(函数式组合)Composition API / 指令
生命周期处理useEffect 管理副作用onMounted / onBeforeUnmount
可读性适合开发者组织逻辑更贴近模板,写法语义直观
复用性Hook 可组合指令可复用在多个模板元素上
构建风格以 JS 逻辑为中心以模板交互为中心

✅ 最佳实践建议

项目类型推荐实现方式
React 应用useClickOutside hook
Vue3 + 组合式项目useClickOutsideVue hook
Vue2 / 模板为主项目v-click-outside 指令

通过合理封装点击外部事件监听逻辑,可以在保持代码整洁的同时,提升组件交互体验与可维护性。


文章转载自:

http://YpNo9Ehp.tbpLf.cn
http://KCAfU2YB.tbpLf.cn
http://u2ON0ROr.tbpLf.cn
http://PBNy9JGg.tbpLf.cn
http://IlfpIiw2.tbpLf.cn
http://KugiD09l.tbpLf.cn
http://jFDcgCSr.tbpLf.cn
http://PZ5HPfFR.tbpLf.cn
http://dyHhIejH.tbpLf.cn
http://z1ZVMsND.tbpLf.cn
http://NUMESV6u.tbpLf.cn
http://Lgktsvdv.tbpLf.cn
http://sLegGoEe.tbpLf.cn
http://UgbnRWYc.tbpLf.cn
http://zGrA25Nh.tbpLf.cn
http://M4CHfVRW.tbpLf.cn
http://hli5F0uY.tbpLf.cn
http://rqB2h9Ye.tbpLf.cn
http://ZchogxrW.tbpLf.cn
http://047eyyyi.tbpLf.cn
http://hkvGwhO4.tbpLf.cn
http://it9Uk1wl.tbpLf.cn
http://fEDjVrrT.tbpLf.cn
http://uZL34yJq.tbpLf.cn
http://5aXFtuW0.tbpLf.cn
http://lArRvzWr.tbpLf.cn
http://zeOqiRr9.tbpLf.cn
http://nwLFE6PG.tbpLf.cn
http://cts1YzJT.tbpLf.cn
http://DkictHz2.tbpLf.cn
http://www.dtcms.com/a/187990.html

相关文章:

  • 深入理解 TypeScript 的 Partial<T> 类型
  • 菜狗的脚步学习
  • [SAP] 通过程序名获取事务码TCode
  • Scala和Go差异
  • c++STL-通用(反向)迭代器适配器
  • 算法第十七天|654. 最大二叉树、617.合并二叉树、700.二叉搜索树中的搜索、98.验证二叉搜索树
  • 第十六章 常用存储器介绍
  • 手机相册的 “智能分类” 功能
  • 数学复习笔记 7
  • Playwright 安装配置文件详解
  • Spark缓存-cache
  • 数据擦除标准:1-Pass vs. 3-Pass vs. 7-Pass有什么区别,哪个更好?
  • 【MySQL】第三弹——表的CRUD进阶(一)数据库约束
  • 专栏特辑丨悬镜浅谈开源风险治理之SBOM与SCA
  • 鸿蒙Next开发 获取APP缓存大小和清除缓存
  • Open Source Geospatial Content Management System -GeoNode
  • 《100天精通Python——基础篇 2025 第18天:正则表达式入门实战,解锁字符串处理的魔法力量》
  • Leetcode 3547. Maximum Sum of Edge Values in a Graph
  • Excelize 开源基础库发布 2.9.1 版本更新
  • win部署Jenkins 自动化部署发布后端项目
  • 6. 多列布局/用户界面 - 杂志风格文章布局
  • RabbitMQ 核心概念与消息模型深度解析(一)
  • centos中libc.so.6No such file的解决方式
  • 尼康VR镜头防抖模式NORMAL和ACTIVE的区别(私人笔记)
  • 专栏项目框架介绍
  • wpf DataGrid 行选择 命令绑定
  • vscode不能跳转到同一个工作区的其他文件夹
  • 阿里二面:聊聊 MySQL 主从同步方案的优缺点
  • 从虚拟现实到混合现实:沉浸式体验的未来之路
  • STM32 变量加载到flash的过程中