Skip to content

useHover

一个鼠标悬停状态管理 Hook,提供简洁的 API 来检测元素的悬停状态。支持延迟触发、自定义事件和条件控制等高级功能。

基础用法

🎯 基础悬停检测

基础悬停

🖱️ 悬停我
悬停状态: 否

卡片悬停效果

🚀
快速启动

一键启动您的项目

高性能

极致的性能体验

🎨
美观设计

精美的界面设计

交互式按钮

高级用法示例

⚡ 高级悬停功能

延迟悬停 (300ms)

🐌 慢慢悬停我 (300ms 延迟)
状态: 等待中...

条件悬停

🔧 条件悬停我

悬停计数器

📊
悬停次数: 0
悬停我增加计数

工具提示

API 参考

参数

参数类型默认值说明
optionsUseHoverOptions{}悬停检测配置选项,包含延迟、回调和启用控制等参数

UseHoverOptions

属性类型默认值说明
immediatebooleantrue是否立即启用检测,设为 false 可以手动控制何时开始监听
onEnter(event: MouseEvent) => void-鼠标进入时的回调函数,可用于执行额外的逻辑
onLeave(event: MouseEvent) => void-鼠标离开时的回调函数,可用于执行额外的逻辑
enterDelaynumber0进入延迟时间(毫秒),可避免快速移动时的误触发
leaveDelaynumber0离开延迟时间(毫秒),可避免鼠标在元素边缘移动时的状态抖动

返回值

useHover 返回一个包含目标元素引用、悬停状态和控制函数的数组:

typescript
const [targetRef, isHovered, setEnabled] = useHover(options);
索引类型说明
0Ref<HTMLElement | null>目标元素的响应式引用,需绑定到要检测悬停状态的元素
1ComputedRef<boolean>悬停状态的只读响应式引用,表示当前元素是否处于悬停中
2(enabled: boolean) => void启用/禁用悬停检测的函数,可动态控制检测功能

类型定义

typescript
export type MouseEnterCallback = (event: MouseEvent) => void;
export type MouseLeaveCallback = (event: MouseEvent) => void;

export interface UseHoverOptions {
  immediate?: boolean;
  onEnter?: MouseEnterCallback;
  onLeave?: MouseLeaveCallback;
  enterDelay?: number;
  leaveDelay?: number;
}

export type UseHoverReturn = [Ref<HTMLElement | null>, ComputedRef<boolean>, SetEnabledFunction];

export function useHover(options?: UseHoverOptions): UseHoverReturn;

使用场景

  1. 交互反馈 - 按钮、卡片、列表项等元素的悬停效果,提供视觉反馈
  2. 工具提示 - 实现悬停时显示的提示信息,增强用户体验
  3. 预览功能 - 悬停预览内容,如图片缩略图、文章摘要等
  4. 导航菜单 - 下拉菜单、级联菜单的显示控制,实现悬停展开
  5. 数据可视化 - 图表元素的高亮显示,突出显示数据点
  6. 图片画廊 - 悬停时显示图片控制按钮或额外信息
  7. 表格交互 - 悬停时高亮行或单元格,显示额外操作按钮
  8. 表单元素 - 为输入框、选择器等提供悬停状态样式

高级用法

延迟控制

通过设置延迟时间,避免用户快速移动鼠标时的频繁状态切换,提升用户体验:

typescript
// 进入延迟 300ms,离开延迟 100ms
const [elementRef, isHovered] = useHover({
  enterDelay: 300, // 鼠标进入后等待 300ms 才触发悬停状态
  leaveDelay: 100, // 鼠标离开后等待 100ms 才取消悬停状态
});

条件启用

根据特定条件动态启用或禁用悬停检测,适用于特定交互场景:

typescript
// 初始不启用悬停检测
const [elementRef, isHovered, setEnabled] = useHover({
  immediate: false,
});

// 动态控制启用状态
const isEnabled = ref(true);
watch(isEnabled, (enabled) => {
  setEnabled(enabled);
});

// 或者根据其他条件控制
watch(isEditing, (editing) => {
  // 编辑模式下禁用悬停效果
  setEnabled(!editing);
});

自定义回调函数

利用回调函数执行额外的逻辑,实现更复杂的交互效果:

typescript
const [elementRef, isHovered] = useHover({
  onEnter: (event) => {
    console.log("鼠标进入", event);
    // 执行额外操作,如加载数据、播放动画等
    loadPreviewData(elementId);
    animateElement(event.target);
  },
  onLeave: (event) => {
    console.log("鼠标离开", event);
    // 执行清理操作
    cancelPreviewLoading();
    resetAnimation(event.target);
  },
});

嵌套悬停检测

组合多个悬停检测实例,实现复杂的嵌套交互效果:

typescript
// 父元素悬停
const [parentRef, isParentHovered] = useHover();
// 子元素悬停
const [childRef, isChildHovered] = useHover();

// 组合悬停状态
const shouldShowDetails = computed(() => {
  return isParentHovered.value || isChildHovered.value;
});

// 使用组合状态控制UI显示
watch(shouldShowDetails, (show) => {
  if (show) {
    showDetailPanel();
  } else {
    hideDetailPanel();
  }
});

悬停统计与分析

结合其他逻辑,实现悬停行为的统计和分析:

typescript
// 悬停计数器
const hoverCount = ref(0);
const [counterRef, isHovered] = useHover({
  onEnter: () => {
    hoverCount.value++;
    // 可以发送统计数据到分析系统
    trackUserInteraction("hover", elementId);
  },
});

// 悬停时长统计
const hoverStartTime = ref<number | null>(null);
const totalHoverTime = ref(0);

const [timerRef] = useHover({
  onEnter: () => {
    hoverStartTime.value = Date.now();
  },
  onLeave: () => {
    if (hoverStartTime.value) {
      const duration = Date.now() - hoverStartTime.value;
      totalHoverTime.value += duration;
      // 记录用户关注时长
      trackEngagementTime(elementId, duration);
      hoverStartTime.value = null;
    }
  },
});

动态样式与动画

结合计算属性,实现基于悬停状态的动态样式和动画效果:

typescript
const [imageRef, isImageHovered] = useHover();

// 动态样式对象
const imageStyle = computed(() => ({
  transform: isImageHovered.value ? "scale(1.1)" : "scale(1)",
  filter: isImageHovered.value ? "brightness(1.2)" : "brightness(1)",
  boxShadow: isImageHovered.value ? "0 10px 20px rgba(0,0,0,0.2)" : "0 2px 5px rgba(0,0,0,0.1)",
  transition: "all 0.3s ease",
}));

注意事项

  1. 自动清理 - 组件卸载时会自动清理事件监听器和定时器,避免内存泄漏
  2. 响应式控制 - 支持动态启用/禁用悬停检测,可根据应用状态灵活控制
  3. 延迟机制 - 使用延迟可以避免频繁的状态切换,提升用户体验
  4. 性能考虑 - 对于大量元素,考虑使用虚拟滚动或按需创建悬停实例
  5. 移动设备 - 在触摸设备上,悬停事件的行为不同,可能需要额外的触摸事件处理
  6. 嵌套元素 - 处理嵌套元素的悬停状态时,注意事件冒泡和捕获的影响
  7. 引用绑定 - 确保正确绑定元素引用,特别是在动态创建的元素上
  8. 类型安全 - 利用 TypeScript 类型定义,确保类型安全和代码提示
  9. 组合使用 - 可与其他 Hooks(如 useFocususeClickOutside)组合使用,实现更复杂的交互
  10. SSR 兼容 - 在服务器端渲染环境中,确保只在客户端执行 DOM 操作

基于 MIT 协议发布