ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

VueUse usePointer 完全指南:Vue 3 中的响应式指针状态监听与指针事件处理

VueUse usePointer 完全指南:Vue 3 中的响应式指针状态监听与指针事件处理 前端【免费下载链接】vueuseCollection of essential Vue Composition Utilities for Vue 3项目地址https://gitcode.com/gh_mirrors/vu/vueuse点击查看免费下载导读usePointer是 VueUsevueuse/core在 Sensors传感器分类下提供的一个组合式函数它将浏览器 Pointer Events指针事件 展开并结合 index.ts、component.ts 与测试用例讲解其全部返回字段、配置参数、组件式用法以及底层实现原理读完后你可以直接在任意 Vue 3 项目中接入指针追踪能力实现绘图、悬停高亮、触摸交互等场景。快速上手基本用法usePointer的默认行为是跟踪window全局窗口上的指针状态。引入并使用它只需要三行代码import { usePointer } from vueuse/core const { x, y, pressure, pointerType } usePointer()解构出的x、y、pressure、pointerType均为 Vue 响应式引用Ref它们会在指针事件触发时自动更新。官方文档中给出的这一段 demo.vue 展示了最直观的调试方式——把整个响应式对象打印在页面上script setup langts import { usePointer } from vueuse/core import { reactive } from vue const pointer reactive(usePointer()) /script template pre classselect-none styletouch-action: none{{ pointer }}/pre /template注意demo 中给pre添加了touch-action: none这是指针事件尤其是触摸场景下的常见实践用于避免浏览器默认的滚动/缩放手势抢占指针事件保证pointermove能持续触发。返回值详解一次拿到完整的指针状态usePointer返回一个对象其中既包含文档示例中提到的x、y、pressure、pointerType也包含更多可用于精细化交互的字段。根据源码 index.ts 中UsePointerReturn接口定义完整返回结构如下字段类型含义xRefnumber指针相对目标默认为窗口的水平坐标yRefnumber指针相对目标默认为窗口的垂直坐标pressureRefnumber指针压力值范围0到1鼠标通常为0.5无压感设备为0或0.5pointerIdRefnumber产生当前事件的指针的唯一标识符tiltXRefnumber指针如触控笔在 X 轴的倾斜角范围-90到90度tiltYRefnumber指针在 Y 轴的倾斜角范围-90到90度widthRefnumber指针接触区域的宽度CSS 像素heightRefnumber指针接触区域的高度CSS 像素twistRefnumber指针围绕自身主轴的顺时针旋转角范围0到359度部分触控笔支持pointerTypeRefPointerType \| null指针类型mouse、touch或penisInsideShallowRefboolean指针是否处于目标区域内部其中PointerType联合类型定义在 types.tsexport type PointerType mouse | touch | pen初始状态在源码 index.ts 的defaultState中定义坐标、压力、倾斜角、尺寸、旋转角均为0pointerType为null。也就是说在用户第一次触发指针事件之前你拿到的x/y等值是0而非undefined这保证了状态始终可安全读取。对于大多数桌面鼠标场景tiltX/tiltY/twist会保持0或由浏览器给出默认值这些字段主要面向触控笔pen输入比如手写板应用中区分笔的倾斜与旋转姿态。配置项详解定制你的监听行为usePointer接受一个可选的options对象。根据UsePointerOptions接口index.ts支持以下配置配置项类型默认值说明targetMaybeRefEventTarget \| null \| undefined \| Document \| Windowwindow监听指针事件的目标对象可为窗口、文档或任意 DOM 元素含 RefpointerTypesPointerType[][mouse, touch, pen]需要监听的指针类型白名单仅匹配的类型会更新状态initialValueMaybeRefPartialUsePointerState{}与默认值合并初始状态值用于自定义指针尚未移动时的默认坐标等windowWindow全局window指定自定义window实例来自ConfigurableWindow见 _configurable.ts适用于 iframe 或测试环境监听特定元素target默认target为defaultWindow客户端环境即全局window见 _configurable.ts。如果要跟踪某个元素内部的局部指针位置把target设为该元素的 Ref 即可script setup langts import { usePointer } from vueuse/core import { useTemplateRef } from vue const el useTemplateRefHTMLElement(board) const { x, y, isInside } usePointer({ target: el }) /script template div refboard styleposition: relative; width: 300px; height: 200px 指针坐标{{ x }}, {{ y }}是否在区域内{{ isInside }} /div /template过滤指针类型pointerTypespointerTypes用于只响应特定输入设备。例如只想处理触控笔pen的压感与倾斜数据、忽略鼠标const { pressure, tiltX, tiltY } usePointer({ pointerTypes: [pen] })源码在 index.ts 中实现了该过滤逻辑事件触发后先检查options.pointerTypes是否存在若存在且不包含event.pointerType则直接返回不更新状态。自定义初始值initialValueinitialValue允许你指定指针未移动前的默认状态。源码 index.ts 的实现是先以defaultState兜底再用用户传入的值覆盖合并const state shallowRef(options.initialValue || {}) as unknown as RefUsePointerState Object.assign(state.value, defaultState, state.value)因此你可以只覆盖部分字段例如const { x, y } usePointer({ initialValue: { x: 100, y: 100 } })源码级原理usePointer是如何工作的理解了用法后深入 index.ts 能帮你彻底掌握其行为边界。核心实现只有约 30 行逻辑非常清晰1. 统一事件处理器handler负责处理三种“激活”事件pointerdown、pointermove、pointerupindex.tsconst handler (event: PointerEvent) { isInside.value true if (options.pointerTypes !options.pointerTypes.includes(event.pointerType as PointerType)) return state.value objectPick(event, keys, false) as UsePointerState }关键点在于objectPick(event, keys, false)它把PointerEvent上的x/y/pressure/pointerId/tiltX/tiltY/width/height/twist/pointerType这些字段批量抽取到状态对象中。objectPick是 VueUse 的工具函数定义在 packages/shared/utils/general.ts其实现是keys.reduce逐键拷贝keys则来源于defaultState的键集合index.ts保证抽取字段与状态结构完全一致。2. 生命周期与事件绑定事件绑定交由useEventListener完成index.tsif (target) { const listenerOptions { passive: true } useEventListener(target, [pointerdown, pointermove, pointerup], handler, listenerOptions) useEventListener(target, [pointerleave, pointercancel], () isInside.value false, listenerOptions) }监听器以{ passive: true }注册避免阻塞滚动同时也就意味着不能在其中调用preventDefault()需要阻止默认行为时应自行在元素上单独绑定事件useEventListener见 packages/core/useEventListener/index.ts会在组件挂载时自动addEventListener、卸载时自动removeEventListener因此usePointer无需手动清理当target为空如 SSR 环境下defaultWindow为undefined时整个监听逻辑被跳过函数依然可以安全调用。3.isInside的语义与边界isInside用于表达“指针是否在目标区域内”pointerdown / pointermove / pointerup→ 置为truepointerleave / pointercancel→ 置为false。需要留意一个边界pointerleave并不总是触发例如在多点触控中第二个触点发起捏合手势时用户代理会直接发送pointercancel而可能不再派发pointerleave。测试文件 index.test.ts 专门覆盖了这个场景——这也是usePointer同时监听pointercancel的原因确保手势被系统接管时isInside仍能及时复位。组件式用法UsePointer除了组合式函数VueUse 还提供了同名渲染组件UsePointer其实现位于 component.ts。组件默认在window上跟踪指针并通过v-slot将全部响应式状态注入插槽template UsePointer v-slot{ x, y } x: {{ x }} y: {{ y }} /UsePointer /template跟踪元素内局部位置targetself组件版的target被收窄为两个字符串取值见 component.ts 的UsePointerPropstemplate UsePointer v-slot{ x, y } targetself x: {{ x }} y: {{ y }} /UsePointer /templatetargetself时组件会把指针跟踪目标指向自身所在的 DOM 元素因此x/y表示指针相对该元素左上角的局部坐标。源码中的实现方式是组件内部维护一个shallowRefHTMLElement | null(null)作为元素引用当props.target self时把它作为target传给usePointer否则使用defaultWindowcomponent.tsconst el shallowRefHTMLElement | null(null) const data reactive(usePointer({ ...props, target: props.target self ? el : defaultWindow, }))组件接收的 props 与组合式函数的 options 完全对应initialValue、pointerTypes、target、window。需要注意的是组件返回的是通过reactive()包装后的数据因此插槽解构出的每个字段都已经具备响应式追踪能力模板中可直接绑定。综合实战可复用的指针绘图/悬停面板把以上知识整合起来下面是一个实用的“局部坐标 类型过滤 边界提示”组合示例同时用到了组合式 API 的关键特性script setup langts import { usePointer } from vueuse/core import { useTemplateRef } from vue const board useTemplateRefHTMLElement(board) const { x, y, pressure, pointerType, isInside } usePointer({ target: board, pointerTypes: [mouse, pen], // 忽略触摸便于统一处理 }) /script template div refboard stylewidth: 100%; height: 300px; touch-action: none; border: 1px solid #888; position: relative; span v-ifisInside 类型{{ pointerType }} 坐标({{ Math.round(x) }}, {{ Math.round(y) }}) 压力{{ pressure.toFixed(2) }} /span span v-else将指针移入区域/span /div /templatetouch-action: none防止触摸滚动干扰pointermove的连续触发通过pointerTypes过滤掉触摸事件后pressure等字段的来源更可控isInside直接驱动“是否在区域内”的提示文案替代繁琐的手动移入/移出判断。使用注意事项与适用前提环境前提usePointer依赖浏览器的 Pointer Events API属于客户端能力。在 SSR服务端渲染环境下defaultWindow为undefined事件监听会被跳过函数可安全执行但状态保持初始值事件不冒泡时当target是具体元素时只有发生在该元素及其子树内的指针事件才会被捕获取决于事件冒泡页面其他区域的指针移动不会更新状态passive: true限制底层监听器以 passive 模式注册不要在usePointer的响应回调里调用preventDefault()否则会收到浏览器警告且无效多点触控pointerId可区分不同的触点若需分别追踪多个触点建议基于usePointer自行维护触点映射或组合使用指针捕获相关 API。结语usePointer以极小的 API 面一个函数、一个组件、三组配置项完整封装了指针事件的常用字段返回值既覆盖x/y坐标这种高频需求也涵盖pressure/tiltX/tiltY/twist/width/height等进阶数据配合isInside与pointerTypes过滤可以应对悬停提示、局部坐标定位、压感绘图、触控笔姿态识别等多种交互场景。若需进一步研究其实现细节可重点阅读 index.ts、component.ts、index.test.ts 以及事件绑定的底层依赖 useEventListener。赞分享前端【免费下载链接】vueuseCollection of essential Vue Composition Utilities for Vue 3项目地址https://gitcode.com/gh_mirrors/vu/vueuse点击查看免费下载相关推荐PyPTO Tensor 操作全指南数学运算与逻辑结构变换实战PyPTO Tensor 操作全指南数学运算与逻辑结构变换实战 PyPTO 作为 Parallel Tensor/Tile Operation 编程范式为昇前端Airi 实战VueUse useEventListener 响应式事件监听完整指南Airi 实战VueUse useEventListener 响应式事件监听完整指南 导读 useEventListener 是 VueUse 提供的浏览器事AI 应用人工智能大模型数字人AI Agent语音前端后端桌面应用移动开发即时通讯3D渲染VueUse useScroll 完整指南响应式滚动位置、边界状态与指令化监听VueUse useScroll 完整指南响应式滚动位置、边界状态与指令化监听 useScroll 是 VueUseVue 3 组合式工具库核心包中位于前端上一篇Node.js 11.8.0Current版本发布深度解析核心亮点、提交清单与发布机制下一篇OpenProject 外部 Wiki 提供方External Wiki Providers集成指南XWiki 配置、OAuth 2.0 认证与运维管理创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表