VueUse onLongPress 详解:元素长按检测的 Hook、组件与指令三种用法

发布时间:2026/10/5 1:49:20
VueUse onLongPress 详解:元素长按检测的 Hook、组件与指令三种用法 前端【免费下载链接】vueuseCollection of essential Vue Composition Utilities for Vue 3项目地址https://gitcode.com/gh_mirrors/vu/vueuse点击查看免费下载导读onLongPress是 VueUseVue 3 组合式工具集中用于监听元素长按Long Press的核心工具位于vueuse/core的 Sensors传感器分类下。它基于浏览器 Pointer Events指针事件实现对鼠标、触屏与触控笔统一生效覆盖 Web 端长按交互最常见的三类诉求触发长按回调、限制移动距离阈值、在抬起时回调统计。读完本文你将掌握onLongPress的函数式 Hook、OnLongPress组件与vOnLongPress指令三种使用姿势以及delay、distanceThreshold、onMouseUp、modifiers等全部选项的底层行为与测试验证方式。一、功能定位与基本用法onLongPress(target, handler, options?)用于在元素上监听长按触发时回调handler并返回一个stop函数用于移除全部监听器。官方文档对它的描述是Listen for a long press on an element. Returns a stop function.基础 Hook 用法在script setup中通过useTemplateRef获取模板引用再调用onLongPressscript setup langts import { onLongPress } from vueuse/core import { shallowRef, useTemplateRef } from vue const htmlRefHook useTemplateRef(htmlRefHook) const longPressedHook shallowRef(false) function onLongPressCallbackHook(e: PointerEvent) { longPressedHook.value true } function resetHook() { longPressedHook.value false } onLongPress( htmlRefHook, onLongPressCallbackHook, { modifiers: { prevent: true } } ) /script template pLong Pressed: {{ longPressedHook }}/p button refhtmlRefHook classml-2 button small Press long /button button classml-2 button small clickresetHook Reset /button /template要点说明target类型为MaybeElementRef见 packages/core/onLongPress/index.ts即既可以直接传 DOM 元素也可以传元素 ref。源码内部通过computed(() unrefElement(target))与 unrefElement 将 ref 统一解析为真实元素因此测试中传 ref与直接传元素两种方式行为一致index.test.ts 分别以 ref 和非 ref 参数跑完整测试套件。handler收到的是原生PointerEvent对象可从中读取clientX、pointerType等信息。返回值OnLongPressReturn即() void调用后清除所有事件监听UseOnLongPressReturn是它的弃用别名仅供向后兼容见 index.ts。二、核心选项详解OnLongPressOptions共包含四个字段delay、distanceThreshold、onMouseUp与modifiers。完整类型声明见 packages/core/onLongPress/index.ts下面是逐一拆解。1. delay长按判定时间默认值500ms源码常量DEFAULT_DELAY见 index.ts。类型number | ((ev: PointerEvent) number)。当传入函数时会在每次pointerdown时以当前事件为参数求值源码getDelay函数index.ts从而实现触屏 800ms、鼠标 500ms这类按指针类型区分的动态延迟import { onLongPress } from vueuse/core // Fixed delay onLongPress(target, handler, { delay: 1000 }) // Dynamic delay based on event onLongPress(target, handler, { delay: ev ev.pointerType touch ? 800 : 500, })测试用例 triggerCallbackWithDelay 验证了设置delay: 1000后按住 500ms 不触发、抬起后也不触发重新按住满 1000ms 才触发一次同时验证了delay为函数时返回 2000同样按函数结果生效。2. distanceThreshold移动距离阈值默认值10像素源码常量DEFAULT_THRESHOLDindex.ts。类型number | false。行为长按进行中若指针相对按下点的位移欧氏距离达到或超过阈值则取消长按清除计时器设为false则完全禁用移动检测手指即使大幅拖动也会在延迟期满后照常触发。import { onLongPress } from vueuse/core // Custom threshold onLongPress(target, handler, { distanceThreshold: 20 }) // Disable movement detection onLongPress(target, handler, { distanceThreshold: false })底层逻辑在onMove中index.ts通过ev.x - posStart.x与ev.y - posStart.y计算距离平方和的平方根distance (options?.distanceThreshold ?? DEFAULT_THRESHOLD)时调用clear()取消计时。测试 triggerCallbackWithThreshold 验证了超出阈值移动后长按不触发而阈值内的小幅移动distanceThreshold: 15下移动约 7.8px不影响触发。3. onMouseUp抬起时回调onMouseUp在指针释放或离开、取消时被调用签名如下onLongPress(target, handler, { onMouseUp(duration, distance, isLongPress, pointerEvent) { console.log(Held for ${duration}ms, moved ${distance}px, long press: ${isLongPress}, x: ${pointerEvent.clientX}) }, })四个参数分别表示参数含义duration按住时长ms由ev.timeStamp - startTimestamp计算index.tsdistance相对按下点的移动距离pxisLongPress是否成功判定为长按即计时器是否已触发过pointerEvent触发释放的原生 PointerEvent这一回调非常适合实现区分点击与长按的交互isLongPress false时视为普通点击。仓库演示 demo.vue 正是用它区分 click 与 long press。注意源码在onRelease中先执行clear()再回调index.ts因此该回调对长按已触发与提前释放两种情况都能感知。测试 triggerOnMouseUp 验证了duration数值与isLongPress在两种场景下的正确性。4. modifiers事件修饰符onLongPress复用了类似 Vue 指令修饰符的语义可用修饰符如下ModifierDescriptionstopCallsevent.stopPropagation()onceRemoves event listener after first triggerpreventCallsevent.preventDefault()captureUses capture mode for event listenerselfOnly trigger if target is the element itselfonLongPress(target, handler, { modifiers: { prevent: true, stop: true, }, })修饰符的底层实现分布在三个环节index.tsprevent/stop在onDown、onMove、onRelease中分别调用preventDefault()与stopPropagation()例如按住时阻止页面滚动、文本选择等默认行为。capture/once直接透传给底层事件监听构成AddEventListenerOptions的capture与once字段。self在onDown/onMove/onRelease中都校验ev.target elementRef.value从而只有点击元素本身而非其子元素时才生效。测试中的佐证workOnceAndPreventModifiersindex.test.ts验证once prevent组合下回调只触发一次且defaultPrevented truestopPropagationL83-L95验证stop修饰符阻止事件冒泡到父元素notTriggerCallbackOnChildLongPressL56-L65验证self修饰符下按住子元素不触发回调。三、内部实现原理事件流与状态机onLongPress的实现非常精简核心是按下计时 移动取消 释放回调三步状态机packages/core/onLongPress/index.tspointerdownonDown记录按下点posStart { x: ev.x, y: ev.y }与时间戳startTimestamp ev.timeStamp然后用setTimeout(..., getDelay(ev))启动长按计时器。pointermoveonMove只要未超出distanceThreshold就保持计时一旦超出则clear()取消。pointerup/pointerleave/pointercancelonRelease先快照并清除状态再调用onMouseUp若提供。事件监听通过 useEventListener 挂载stop返回函数会对四个监听器逐一执行清理index.ts。三个值得注意的实现细节长按回调在setTimeout中执行时传递的是按下时的原始 PointerEventonDown闭包捕获的ev而不是移动或抬起时的事件。状态变量posStart、startTimestamp、hasLongPressed每次按下都会先被clear()重置因此重复按下互不干扰测试triggerCallbackWithDelay正是验证了第一次按住 500ms 后抬起不触发第二次按住满 1000ms 触发一次。pointercancel也走onRelease因此浏览器接管手势例如第二个手指开始捏合缩放时会取消长按测试 notTriggerCallbackOnPointerCancel 验证了这一点。四、组件用法OnLongPress除了 HookVueUse 还提供了渲染组件OnLongPress从vueuse/components导入适合在模板中声明式使用script setup langts import { OnLongPress } from vueuse/components import { shallowRef } from vue const longPressedComponent shallowRef(false) function onLongPressCallbackComponent(e: PointerEvent) { longPressedComponent.value true } function resetComponent() { longPressedComponent.value false } /script template pLong Pressed: {{ longPressedComponent }}/p OnLongPress asbutton classml-2 button small triggeronLongPressCallbackComponent Press long /OnLongPress button classml-2 button small clickresetComponent Reset /button /template组件机制见 packages/core/onLongPress/component.ts通过as属性指定渲染标签默认div类型来自RenderableComponent见 packages/core/types.ts。通过options属性透传全部OnLongPressOptions。长按触发时 emittrigger事件携带原生 PointerEvent。组件内部用shallowRef持有渲染根节点作为监听目标默认插槽会注入useOnLongPressReturn数据方便在插槽内读取 stop 函数等。五、指令用法vOnLongPressvOnLongPress指令同样从vueuse/components导入提供最简洁的模板语法两种绑定形式script setup langts import { vOnLongPress } from vueuse/components import { shallowRef } from vue const longPressedDirective shallowRef(false) function onLongPressCallbackDirective(e: PointerEvent) { longPressedDirective.value true } function resetDirective() { longPressedDirective.value false } /script template pLong Pressed: {{ longPressedDirective }}/p !-- 使用 .prevent 修饰符 -- button v-on-long-press.preventonLongPressCallbackDirective classml-2 button small Press long /button !-- 使用数组形式传入回调与选项 -- button v-on-long-press[onLongPressCallbackDirective, { delay: 1000, modifiers: { stop: true } }] classml-2 button small Press long (with options) /button button classml-2 button small clickresetDirective Reset /button /template指令实现见 packages/core/onLongPress/directive.ts基于createDisposableDirective绑定的值若为函数则直接作为 handler并把模板上的指令修饰符.prevent、.stop等作为modifiers传入若为[handler, options]数组则同时展开回调与完整OnLongPressOptions指令在mounted时注册监听组件卸载时由createDisposableDirective自动清理监听器。指令测试见 directive.test.ts无选项时按住 500ms 触发一次传入delay: 1000时按住 500ms 不触发、满 1000ms 触发卸载后pointerdown不再触发回调。六、三种用法的选型建议与注意事项场景推荐用法理由逻辑密集、需与响应式状态联动、动态控制监听开关HookonLongPress可编程、返回 stop 函数、参数全部可配置模板优先、希望以组件语义声明交互组件OnLongPress声明式、可自定义渲染标签、事件驱动追求最简模板、复用原生指令修饰符习惯指令vOnLongPress一行绑定、自动清理、支持.prevent等修饰符实操注意事项长按与浏览器默认行为的冲突如长按触发系统菜单、选中文本、滚动可通过prevent: true或stop: true修饰符缓解必要时结合 CSSuser-select: none。distanceThreshold的默认 10px 对触屏用户可能偏小可按需调大如 20~24px仓库 demo 即使用 24px 与 1000ms 组合演示长按或点击场景demo.vue。delay作为函数时基于事件动态求值可用于区分pointerTypemouse | touch | pen见 types.ts兼顾不同输入设备的操作习惯。函数式用法的返回 stop 函数请在组件卸载时调用以释放监听组件与指令用法则由 VueUse 自动完成清理。七、源码结构与快速上手路径onLongPress相关文件全部位于 packages/core/onLongPress/ 目录文件作用index.tsHook 核心实现与全部类型声明component.tsOnLongPress渲染组件directive.tsvOnLongPress指令index.test.tsHook 的完整行为测试9 个用例directive.test.ts指令的挂载、触发与卸载清理测试demo.vue演示不同 delay / 阈值 / onMouseUp 组合的交互示例index.md官方文档本仓库 skills/vueuse-functions/references/onLongPress.md 的知识来源从入口看vueuse/core通过 packages/core/index.ts 的export * from ./onLongPress导出 Hookpackages/components/index.ts 同时导出组件与指令因此三条使用路径分别对应vueuse/core与vueuse/components两个包的导入。从源码结构看onLongPress 不依赖任何浏览器专属 API 的 polyfill仅依赖 Pointer Events 与setTimeout实现轻盈、可测试性高非常适合作为学习 VueUse 组合式工具实现风格的入门范本。赞分享前端【免费下载链接】vueuseCollection of essential Vue Composition Utilities for Vue 3项目地址https://gitcode.com/gh_mirrors/vu/vueuse点击查看免费下载相关推荐VueUse onLongPress 完整指南Vue 3 长按交互的侦听、配置与组件/指令用法VueUse onLongPress 完整指南Vue 3 长按交互的侦听、配置与组件/指令用法 onLongPress 是 VueUse 为 Vue 3 提供前端VueUse 的 useElementOverflow响应式检测元素溢出状态组合式、组件与指令三种用法全解析VueUse 的 useElementOverflow响应式检测元素溢出状态组合式、组件与指令三种用法全解析 useElementOverflow 是 V前端VueUse 的 useIntersectionObserver 全面指南元素可见性检测、响应式监听与指令用法VueUse 的 useIntersectionObserver 全面指南元素可见性检测、响应式监听与指令用法 导读 useIntersectionObser前端上一篇DevOps事件管理工具GitHub_Trending/aw/awesome-devops平台事件响应平台下一篇tsParticles Export JSON 插件实战把粒子配置一键导出为 JSON 文件创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

关于本文作者

来自尧图内容编辑团队

尧图内容编辑团队 内容团队

尧图内容编辑团队

本文由尧图网络内容编辑团队执笔。团队由资深项目经理、前端工程师与设计师组成,所有内容均来自亲手交付的真实项目,先讲清问题、再给出可落地的解法。尧图深耕北京网站建设十年,服务过京华建材集团、智造科技等各行业客户,把一线经验沉淀为可复用的行业观察。

  • 十年建站经验,覆盖建材、制造、服务、文创等
  • 项目经理把关选题与事实准确性
  • 工程师与设计师联合撰写专业细节
  • 统一编辑规范,保证文风与排版一致
  • 每月复盘转化数据,迭代选题方向

延伸阅读

相关资讯与近期热门内容

深度阅读推荐

建站决策前值得细读的三篇

网站改版的5个关键决策
2024-08-12

网站改版的5个关键决策

什么时候该改版、改到什么程度、如何避免流量掉光,京华建材集团改版复盘给出答案。

获取专属建站方案

看完文章,把您的行业与预算告诉我们,免费获取一份量身定制的官网建设方案与报价。

立即免费咨询