文字提示
概述
当元素获得键盘焦点或鼠标悬停时,显示与该元素相关信息的弹出层。STooltip 组合 Aria TooltipRoot/TooltipTrigger/TooltipPositioner/TooltipPopup/TooltipArrow 基础组件家族(构建于共享 Popper)与 tooltipVariants 样式配方(3 个槽、6 种尺寸)。
文字提示适合简短、不可交互的提示。丰富的悬停内容请用 hover-card;点击触发的内容请用 popover;确认请用 popconfirm。
用法
特性
- 🧩 Aria/样式分离 —
TooltipCompact聚合 popper 触发器、定位器、弹层与箭头;STooltip只注入样式并转发插槽/事件 - 🖱️ 悬停 + 焦点 — 指针悬停或键盘焦点时打开;Escape 或指针离开时关闭
- ⏱️ 延迟调节 —
delayDuration(打开)与skipDelayDuration(触发间隔),全局默认值经ConfigProvider - 🎯 定位 — 完整 popper
placement控制,带碰撞避免与按侧滑入动画 - 🔽 箭头 —
showArrow渲染定位箭头;经arrowProps可配置 - 🏷️ 内容 —
contentprop 或默认插槽 - ♿ 行为开关 —
ignoreNonKeyboardFocus、disableHoverableContent、disableClosingTrigger、disabled - 📐 6 种尺寸 — xs–2xl
size;逐槽ui覆盖 - ♿ 无障碍 —
role="tooltip"(视觉隐藏文本节点)、非模态、打开与关闭时axe-core零违规
组件家族
STooltip(样式层)— 入口包装组件;tooltipVariants配方配合动态插槽转发TooltipRoot(Aria)— 状态持有者;经useControllableState维护open,提供delayDuration/skipDelayDuration/disabled/ignoreNonKeyboardFocus,合并全局ConfigProvidertooltip 配置TooltipTrigger(Aria)— 悬停/聚焦打开提示的锚点TooltipPositioner/TooltipPositionerImpl(Aria)— 定位表面(构建于PopperPositioner)TooltipPopup(Aria)— 弹层主体;暴露视觉隐藏的role="tooltip"文本节点供屏幕阅读器TooltipArrow(Aria)— popper 箭头TooltipCompact(Aria)— 聚合组件;组合触发器/定位器/弹层/箭头并暴露各插槽
演示
基础
API
Aria 层
9Tooltip
属性
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
class | ClassValue | — | 弹出窗口类 |
size | ThemeSize | — | 组件的视觉尺寸。 |
ui | Partial<TooltipUi> | — | 该组件的按槽类重写。 |
content | string | — | 内容。 |
placement | Placement | — | 位置。 |
showArrow | boolean | — | 是否显示箭头。 |
triggerProps | PopperAnchorProps | — | 转发给触发元素的属性。 |
portalProps | TooltipPortalProps | — | 转发给 portal 元素的属性。 |
positionerProps | TooltipPositionerProps | — | 转发给定位器元素的属性。 |
popupProps | TooltipPopupProps | — | 转发给弹出窗口元素的属性。 |
arrowProps | TooltipArrowProps | — | 转发给箭头元素的属性。 |
defaultOpen | boolean | — | 工具提示在初始渲染时的打开状态。当您无需控制其打开状态时使用此选项。 |
open | boolean | — | 工具提示的受控打开状态。 |
dir | Direction | — | — |
modal | boolean | — | — |
disabled | boolean | — | 当值为 `true` 时,禁用工具提示 |
delayDuration | number | 150 | 从指针进入触发区域到工具提示打开所花费的时间。 |
skipDelayDuration | number | 300 | 用户在触发延迟之前,有多少时间可以输入另一个触发条件。 |
disableHoverableContent | boolean | false | 当设置为 `true` 时,尝试将鼠标悬停在内容上,当指针离开触发区域时,工具提示将关闭。 |
disableClosingTrigger | boolean | false | 当值为 `true` 时,点击触发器不会关闭内容。 |
ignoreNonKeyboardFocus | boolean | false | 通过匹配
`:focus-visible` 选择器,防止在焦点非来自键盘时打开工具提示。如果希望在切换浏览器标签页或关闭
对话框时避免打开工具提示,此方法非常有用。 |
事件
| 事件名 | 参数 | 描述 |
|---|---|---|
update:open | boolean, reason?: PopperOpenChangeReason | undefined | 当工具提示的打开状态发生变化时,会调用此事件处理程序。 |
escapeKeyDown | KeyboardEvent | 当 Esc 键被按下时触发的事件处理程序。可被阻止。 |
pointerDownOutside | PointerDownOutsideEvent | 当 `pointerdown` 事件发生在 `DismissableLayer` 外部时调用的事件处理程序。可被阻止。 |
focusOutside | FocusOutsideEvent | 当焦点移出 `DismissableLayer` 时触发的事件处理程序。可被阻止。 |
interactOutside | PointerDownOutsideEvent | FocusOutsideEvent | 当在 `DismissableLayer` 外部发生交互时触发的事件处理程序。具体而言,当 `pointerdown`
事件在该区域外部发生,或焦点移出该区域时触发。此事件可被阻止。 |
openAutoFocus | Event | 在打开页面时自动聚焦时触发的事件处理程序。可被阻止。 |
closeAutoFocus | Event | 在关闭时自动聚焦时触发的事件处理程序。可被阻止。 |
placed | — | — |
插槽
| 插槽名 | 参数 | 描述 |
|---|---|---|
default | — | 默认插槽的自定义内容。 |
trigger | — | 触发槽的自定义内容。 |
TooltipArrow
TooltipCompact
属性
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
content | string | — | 内容。 |
placement | Placement | — | 位置。 |
showArrow | boolean | — | 是否显示箭头。 |
triggerProps | PopperAnchorProps | — | 转发给触发元素的属性。 |
portalProps | TooltipPortalProps | — | 转发给 portal 元素的属性。 |
positionerProps | TooltipPositionerProps | — | 转发给定位器元素的属性。 |
popupProps | TooltipPopupProps | — | 转发给弹出窗口元素的属性。 |
arrowProps | TooltipArrowProps | — | 转发给箭头元素的属性。 |
defaultOpen | boolean | — | 工具提示在初始渲染时的打开状态。当您无需控制其打开状态时使用此选项。 |
open | boolean | — | 工具提示的受控打开状态。 |
dir | Direction | — | — |
modal | boolean | — | — |
disabled | boolean | — | 当值为 `true` 时,禁用工具提示 |
delayDuration | number | 150 | 从指针进入触发区域到工具提示打开所花费的时间。 |
skipDelayDuration | number | 300 | 用户在触发延迟之前,有多少时间可以输入另一个触发条件。 |
disableHoverableContent | boolean | false | 当设置为 `true` 时,尝试将鼠标悬停在内容上,当指针离开触发区域时,工具提示将关闭。 |
disableClosingTrigger | boolean | false | 当值为 `true` 时,点击触发器不会关闭内容。 |
ignoreNonKeyboardFocus | boolean | false | 通过匹配
`:focus-visible` 选择器,防止在焦点非来自键盘时打开工具提示。如果希望在切换浏览器标签页或关闭
对话框时避免打开工具提示,此方法非常有用。 |
事件
| 事件名 | 参数 | 描述 |
|---|---|---|
update:open | boolean, reason?: PopperOpenChangeReason | undefined | 当工具提示的打开状态发生变化时,会调用此事件处理程序。 |
escapeKeyDown | KeyboardEvent | 当 Esc 键被按下时触发的事件处理程序。可被阻止。 |
pointerDownOutside | PointerDownOutsideEvent | 当 `pointerdown` 事件发生在 `DismissableLayer` 外部时调用的事件处理程序。可被阻止。 |
focusOutside | FocusOutsideEvent | 当焦点移出 `DismissableLayer` 时触发的事件处理程序。可被阻止。 |
interactOutside | PointerDownOutsideEvent | FocusOutsideEvent | 当在 `DismissableLayer` 外部发生交互时触发的事件处理程序。具体而言,当 `pointerdown`
事件在该区域外部发生,或焦点移出该区域时触发。此事件可被阻止。 |
openAutoFocus | Event | 在打开页面时自动聚焦时触发的事件处理程序。可被阻止。 |
closeAutoFocus | Event | 在关闭时自动聚焦时触发的事件处理程序。可被阻止。 |
placed | — | — |
插槽
| 插槽名 | 参数 | 描述 |
|---|---|---|
default | — | 默认插槽的自定义内容。 |
trigger | — | 触发槽的自定义内容。 |
TooltipPopup
属性
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
ariaLabel | string | — | 默认情况下,屏幕阅读器会朗读组件内的内容。
如果描述不够详细,或者存在无法被朗读的内容,请使用 `aria-label` 作为更具
描述性的标签。 |
TooltipPortal
TooltipPositioner
属性
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
placement | Placement | undefined | 浮动元素的位置。
若使用该属性,它将覆盖 `side` 和 `align` 属性。 |
side | Side | 'bottom' | 打开时优先渲染的触发器一侧。当发生碰撞且
enableAvoidCollisions 启用时,该方向将被反转。 |
sideOffset | number | 0 | 距触发器的像素距离。 |
sideFlip | boolean | true | 遇到边界时,请翻转至另一侧。 |
align | Align | 'center' | 首选与触发条件保持一致。若发生冲突,则可能调整。 |
alignOffset | number | 0 | 相对于 `start` 或 `end` 对齐选项的像素偏移量。 |
alignFlip | boolean | true | 当与边界发生冲突时,翻转对齐方式。
此情况仅在 `prioritizePosition` 为 true 时才会发生。 |
avoidCollisions | boolean | true | 当值为 `true` 时,将覆盖“侧边”和“对齐”首选项,以避免与边界边缘发生冲突。 |
collisionBoundary | Element | (Element | null)[] | null | [ ] | 用作碰撞边界的元素。默认情况下,该边界为视口,但您可以提供额外的
元素以纳入此检查范围。 |
collisionPadding | Padding | 0 | 从边界边缘开始,碰撞检测应发生的距离(以像素为单位)。接受一个数字(
所有边均相同),或一个部分填充对象,例如:{ top: 20, left: 20 }。 |
arrowPadding | number | 0 | 箭头与内容边缘之间的间距。如果您的内容使用了 border-radius,这将防止内容
溢出到角落。 |
hideShiftedArrow | boolean | true | 当值为 `true` 时,若无法将箭头居中对齐
到引用元素上,则隐藏该箭头。 |
sticky | 'partial' | 'always' | 'partial' | 在对齐轴上的“粘附”行为。`partial` 会在触发器至少部分位于边界内时将内容保留在边界内,而
“always” 则无论触发器是否位于边界内,都会将内容保留在边界内。 |
hideWhenDetached | boolean | false | 当触发器被完全遮挡时,是否隐藏内容。 |
positionStrategy | 'fixed' | 'absolute' | 'fixed' | 要使用的 CSS `position` 属性的类型。 |
updatePositionStrategy | 'always' | 'optimized' | 'optimized' | 在每个动画帧中更新浮动元素位置的策略。 |
disableUpdateOnLayoutShift | boolean | false | 当布局发生变化时,是否禁用内容的更新位置。 |
prioritizePosition | boolean | false | 强制内容位于视口内。可能会与参考元素重叠,这可能并非预期效果。 |
reference | ReferenceElement | — | 将作为浮动元素定位参考点的自定义元素或虚拟元素。如果
提供了该元素,它将替换默认的锚点元素。 |
trapFocus | boolean | modal | 弹出窗口打开时,焦点是否被困在其中(Tab 键在层内循环,且
模态层的页面滚动被锁定)。 |
disableHoverableContent | boolean | false | 当设置为 `true` 时,鼠标悬停会关闭弹出窗口而非保持其打开状态(宽限区域已禁用,
因此离开触发区域会立即关闭该层)。 |
onGracePointerExit | (() => void) | — | 当指针最终离开宽限区域时触发的回调。允许上层组件(例如
Tooltip)在无需注册自己的第二个宽限区域的情况下,执行区域范围内的关闭逻辑。 |
forceMount | boolean | — | 用于在需要更多控制时强制挂载。
在使用 Vue 动画库控制动画时非常有用。 |
事件
| 事件名 | 参数 | 描述 |
|---|---|---|
escapeKeyDown | KeyboardEvent | 当 Esc 键被按下时触发的事件处理程序。可被阻止。 |
pointerDownOutside | PointerDownOutsideEvent | 当 `pointerdown` 事件发生在 `DismissableLayer` 外部时调用的事件处理程序。可被阻止。 |
focusOutside | FocusOutsideEvent | 当焦点移出 `DismissableLayer` 时触发的事件处理程序。可被阻止。 |
interactOutside | PointerDownOutsideEvent | FocusOutsideEvent | 当在 `DismissableLayer` 外部发生交互时触发的事件处理程序。具体而言,当 `pointerdown`
事件在该区域外部发生,或焦点移出该区域时触发。此事件可被阻止。 |
openAutoFocus | Event | 在打开页面时自动聚焦时触发的事件处理程序。可被阻止。 |
closeAutoFocus | Event | 在关闭时自动聚焦时触发的事件处理程序。可被阻止。 |
placed | — | — |
TooltipProvider
属性
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
delayDuration | number | 150 | 从指针进入触发区域到工具提示打开所花费的时间。 |
skipDelayDuration | number | 300 | 用户在触发延迟之前,有多少时间可以输入另一个触发条件。 |
disableHoverableContent | boolean | false | 当设置为 `true` 时,尝试将鼠标悬停在内容上,当指针离开触发区域时,工具提示将关闭。 |
disableClosingTrigger | boolean | false | 当值为 `true` 时,点击触发器不会关闭内容。 |
disabled | boolean | false | 当值为 `true` 时,禁用工具提示 |
ignoreNonKeyboardFocus | boolean | false | 通过匹配
`:focus-visible` 选择器,防止在焦点非来自键盘时打开工具提示。如果希望在切换浏览器标签页或关闭
对话框时避免打开工具提示,此方法非常有用。 |
positionerProps | TooltipPositionerProps | — | 将传递给定位器的 props。当需要控制定位器时(例如在触发器禁用时禁用定位器),此功能非常有用。 |
TooltipRoot
属性
| 属性名 | 类型 | 默认值 | 描述 |
|---|---|---|---|
defaultOpen | boolean | — | 工具提示在初始渲染时的打开状态。当您无需控制其打开状态时使用此选项。 |
open | boolean | — | 工具提示的受控打开状态。 |
dir | Direction | — | — |
modal | boolean | — | — |
disabled | boolean | — | 当值为 `true` 时,禁用工具提示 |
delayDuration | number | 150 | 从指针进入触发区域到工具提示打开所花费的时间。 |
skipDelayDuration | number | 300 | 用户在触发延迟之前,有多少时间可以输入另一个触发条件。 |
disableHoverableContent | boolean | false | 当设置为 `true` 时,尝试将鼠标悬停在内容上,当指针离开触发区域时,工具提示将关闭。 |
disableClosingTrigger | boolean | false | 当值为 `true` 时,点击触发器不会关闭内容。 |
ignoreNonKeyboardFocus | boolean | false | 通过匹配
`:focus-visible` 选择器,防止在焦点非来自键盘时打开工具提示。如果希望在切换浏览器标签页或关闭
对话框时避免打开工具提示,此方法非常有用。 |
positionerProps | TooltipPositionerProps | — | 将传递给定位器的 props。当需要控制定位器时(例如在触发器禁用时禁用定位器),此功能非常有用。 |
事件
| 事件名 | 参数 | 描述 |
|---|---|---|
update:open | boolean, reason?: PopperOpenChangeReason | undefined | 当工具提示的打开状态发生变化时,会调用此事件处理程序。 |
TooltipTrigger
注意事项
架构与对标差异
TooltipCompact 负责触发器/定位器/弹层/箭头组合,所有基础组件保持零样式,仅由 UI 包装组件注入 tooltipVariants 类。这与 radix-ui/shadcn-ui 的 headless 分离一致,构建于共享 Popper 基础组件之上。Ant Design、Element Plus、Mantine、Naive UI 提供带 title/placement prop 的单一样式化提示;VeanUI 额外暴露逐槽 *Props、size 尺寸体系、箭头开关、带 ConfigProvider 全局默认的 delayDuration/skipDelayDuration 调节模型,以及无障碍的视觉隐藏 role="tooltip" 节点。
| 能力 | VeanUI | shadcn/ui | Ant Design Tooltip | Element Plus Tooltip | Mantine Tooltip | Naive UI Tooltip |
|---|---|---|---|---|---|---|
| Aria/样式分离 | ✅ | ✅ | — | — | — | — |
| Popper 定位(12) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| 延迟调节 | ✅ | ✅ | — | ✅ | ✅ | — |
| 箭头 | ✅ | ✅ | — | — | — | — |
| 尺寸(6) | ✅ | — | — | — | — | — |
| 焦点触发 | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
— = 不支持或采用不同交互模型。
运行时注意
- 提示在悬停与键盘焦点时打开;调节
delayDuration/skipDelayDuration(或ConfigProvider的 tooltip 默认)以减少误触发。 ignoreNonKeyboardFocus(默认)忽略非键盘焦点(如编程式),符合原生提示语义。- 弹层经
Portal渲染(传送至document.body);仅在portalProps: { disabled: true }时置于相对定位的祖先内。 showArrow渲染箭头;arrowProps可覆盖其位置/类。- 提示非模态、不陷阱焦点;Escape 或指针离开时关闭。
Roadmap
不适用——tooltip 对当前对标集已功能完备。
FAQ
如何给元素添加文字提示?
将元素包进 trigger 插槽并设置 content:
<STooltip content="删除此项">
<template #trigger><SButton>删除</SButton></template>
</STooltip>如何定位提示?
使用 placement:
<STooltip placement="top" content="复制">
<template #trigger><SButton>复制</SButton></template>
</STooltip>如何调整打开时机?
设置 delay-duration(毫秒),并用 skip-delay-duration 控制触发间隔:
<STooltip :delay-duration="150" :skip-delay-duration="50" content="保存">
<template #trigger><SButton>保存</SButton></template>
</STooltip>如何隐藏箭头?
设置 show-arrow={false}:
<STooltip :show-arrow="false" content="信息">
<template #trigger><SButton>?</SButton></template>
</STooltip>