airi 项目实战:用 VueUse useElementHover 响应式追踪元素悬停状态
airi 项目实战用 VueUse useElementHover 响应式追踪元素悬停状态【免费下载链接】airi Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-samas altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi本文以 airi 仓库内.agents/skills/vueuse-functions技能包中的useElementHover参考文档为主体讲解如何用 VueUse 的useElementHover组合式函数composable响应式地追踪 DOM 元素的鼠标悬停状态覆盖组合式用法、指令用法v-element-hover、可配置选项与类型声明并结合仓库源码如 round-range.vue 的实际调用说明其在真实组件中的落地方式。读完本文你可以在任何 Vue 3 / Nuxt 3 项目中用最小代码量实现悬停感知交互并理解其背后的参数语义。什么是 useElementHoveruseElementHover是 VueUse 中位于Sensors传感器分类下的一个组合式函数其核心能力是将某个 DOM 元素的 hover鼠标悬停状态变成一个响应式引用reactive ref。它在 SKILL.md 中被描述为 Reactive elements hover state且调用规则为AUTO——即只要在 Vue.js / Nuxt 开发中遇到需要感知元素悬停状态的场景就应当优先考虑使用它而不是手写mouseenter/mouseleave事件监听。在 airi 这个多端Web / macOS / Windows / Electron项目中VueUse 是渲染层的基础依赖。以 apps/stage-web/package.json 与 packages/ui/package.json 为例两者均通过 pnpm workspace 的catalog:协议声明了vueuse/core依赖packages/ui还承载着大量可复用 UI 组件。因此理解useElementHover对阅读和扩展 airi 的 UI 层代码有直接价值。基本用法组合式 APIuseElementHover接受一个目标元素的引用ref或 getter返回一个ShallowRefboolean悬停时为true离开时为false。参考文档给出的最小示例引自 useElementHover.mdscript setup langts import { useElementHover } from vueuse/core import { useTemplateRef } from vue const myHoverableElement useTemplateRef(myHoverableElement) const isHovered useElementHover(myHoverableElement) /script template button refmyHoverableElement {{ isHovered }} /button /template几个值得注意的要点使用 Vue 3.5 的useTemplateRef来声明模板 ref与useElementHover的MaybeRefOrGetter参数签名天然匹配返回值是ShallowRefboolean因此模板中可以直接插值渲染也可以被watch、computed继续消费不需要手动添加/移除mouseenter/mouseleave监听器生命周期由 VueUse 内部自动管理。在 airi 的源码中useElementHover被真实用于圆形滑杆组件 round-range.vueconst sliderRef refHTMLInputElement() const isHovered useElementHover(sliderRef)随后组件通过watch(isHovered, ...)在悬停时动态挂载/卸载wheel事件监听实现鼠标悬停在滑杆上时才能用滚轮调节数值的交互round-range.vuewatch(isHovered, (hovered: boolean) { if (!props.handleWheel) return if (hovered) { sliderRef.value?.addEventListener(wheel, onWheelInput) return } sliderRef.value?.removeEventListener(wheel, onWheelInput) })这是一个非常典型的实战模式用悬停状态驱动副作用开关比在模板里反复判断mouseenter/mouseleave更干净、更集中。指令用法 v-element-hover除了组合式函数VueUse 还通过vueuse/components提供了指令形式v-element-hover适合只想在模板里声明式绑定回调的场景。基础指令形式参考文档示例引自 useElementHover.mdscript setup langts import { vElementHover } from vueuse/components import { shallowRef } from vue const isHovered shallowRef(false) function onHover(state: boolean) { isHovered.value state } /script template button v-element-hoveronHover {{ isHovered ? Thank you! : Hover me }} /button /template指令的绑定值是一个回调函数悬停状态变化时会被调用参数为当前悬停布尔值。这种方式把状态管理与模板声明解耦——状态值由外部shallowRef维护指令只负责上报事件。带选项的指令形式v-element-hover还支持以数组形式传入「回调 选项」script setup langts import { vElementHover } from vueuse/components import { shallowRef } from vue const isHovered shallowRef(false) function onHover(hovered: boolean) { isHovered.value hovered } /script template button v-element-hover[onHover, { delayEnter: 1000 }] span{{ isHovered ? Thank you! : Hover me }}/span /button /template上面的示例配置了delayEnter: 1000即鼠标进入元素 1000ms 后才上报 hover 状态——这对悬停停留一段时间才触发浮层/提示的交互非常有用可以避免用户快速划过时误触发。选项与类型声明useElementHover的完整类型声明如下引自 useElementHover.mdexport interface UseElementHoverOptions extends ConfigurableWindow { delayEnter?: number delayLeave?: number triggerOnRemoval?: boolean } export declare function useElementHover( el: MaybeRefOrGetterEventTarget | null | undefined, options?: UseElementHoverOptions, ): ShallowRefboolean各选项语义如下选项类型默认值说明delayEnternumber未设置进入悬停状态后延迟多少毫秒再置为truedelayLeavenumber未设置离开元素后延迟多少毫秒再置为false如用于等待浮层过渡动画triggerOnRemovalbooleanfalse元素从 DOM 中移除时是否立即触发一次离开回调避免事件丢失继承自ConfigurableWindow——可配置window对象用于 SSR 或非浏览器环境下的测试注入参数el接受MaybeRefOrGetterEventTarget | null | undefined意味着你可以传入元素 ref、返回元素的 getter 函数、甚至原始null元素尚未挂载时安全。返回值ShallowRefboolean保证了状态更新的性能——浅层响应式不会触发深层依赖重算。在 airi 中的周边生态Electron 下的悬停感知airi 是一个跨 Web / Electron 桌面的项目其packages/electron-vueuse包基于 VueUse 的模式扩展了 Electron 场景下的鼠标能力例如use-electron-mouse-in-element.ts将鼠标位置与元素边界关联use-electron-mouse.ts响应式鼠标位置use-electron-mouse-in-window.ts鼠标是否在窗口内。这些 composable 与useElementHover同属传感器思路把浏览器的鼠标/指针事件收敛为响应式状态供 UI 层声明式消费。如果你在 airi 的桌面端apps/stage-tamagotchi实现类似悬停桌面窗口边缘才显示控制条的需求可以复用同样的设计模式先由 composable 产出响应式布尔状态再用watch驱动 UI 副作用。实战建议与最佳实践优先 composable其次指令函数形式返回的状态可被computed、watch、v-model链路自由组合可测试性更强指令形式适合模板内快速声明。用延迟选项过滤噪声需要悬停停留语义如 Tooltip、下拉浮层时设置delayEnter需要平滑消失时设置delayLeave。结合watch做副作用开关参考 round-range.vue 的做法在watch(isHovered)里按需挂载/卸载高开销监听器避免常驻监听带来的性能开销。注意 SSR 与triggerOnRemoval服务端渲染或元素动态销毁的场景下合理设置ConfigurableWindow与triggerOnRemoval可避免事件遗漏与窗口引用错误。作为技能库的一部分使用airi 将完整的 VueUse 参考文档收纳在 .agents/skills/vueuse-functions/references 下写作 Vue 组件时可以先查该技能库确认是否有现成 composable 可复用其SKILL.md明确要求遇到需求先查 VueUse 是否可实现。通过useElementHover悬停状态从一对事件监听器变成一个响应式布尔值这正是 VueUse 组合式 API 让 UI 逻辑保持简洁、可维护、可组合的典型体现。【免费下载链接】airi Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-samas altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考