TinyVue 自定义指令 v-auto-tip:文本超长自动提示的优雅方案
还在手动给每个可能超长的文本加 tooltip?醒醒吧,2026 年了!TinyVue 的
v-auto-tip指令帮你一键搞定——鼠标移入时自动探测文本是否溢出,溢出就弹出提示,不溢出就安静如鸡。这才是"智能"该有的样子。
一、痛点:文本溢出的"手动地狱"
做前端的同学一定遇到过这种场景:表格列太窄、标签太长、侧边栏菜单文字溢出……然后你就开始:
- 给每个元素加
overflow: hidden; text-overflow: ellipsis; white-space: nowrap; - 再给每个元素包一层
<tiny-tooltip> - 判断文字是否真的超长了,超长才显示 tooltip
- 写一堆重复的逻辑……
更痛苦的是,数据是动态的——今天这条数据不超长,明天换了条数据就超长了。手动管理?别闹了。
TinyVue 的 v-auto-tip 自定义指令,就是为了终结这种重复劳动而生的。
二、基本用法:一行指令,搞定一切
v-auto-tip 的核心逻辑很简单:鼠标移入元素时,自动探测文本内容是否超出容器宽度,如果超出了,就自动挂载一个 tooltip 显示完整文本。
来看最基础的用法:
<template>
<div class="auto-tip" v-auto-tip>
超出省略隐藏,鼠标移入会有 ToolTip 提示
</div>
</template>
<script>
import { AutoTip } from '@opentiny/vue-directive'
export default {
directives: { AutoTip }
}
</script>
<style scoped>
.auto-tip {
width: 120px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>
如果你用的是 Composition API(<script setup>),写法稍有不同:
<template>
<div class="auto-tip" v-auto-tip>
超出省略隐藏,鼠标移入会有 ToolTip 提示
</div>
</template>
<script setup>
import { AutoTip } from '@opentiny/vue-directive'
const VAutoTip = AutoTip
</script>
<style scoped>
.auto-tip {
width: 120px;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>
关键要点
- 必须给元素添加溢出省略样式:
v-auto-tip只负责探测和弹出 tooltip,它不会自动帮你加上overflow: hidden等样式。你需要自己确保元素有超出省略的 CSS,否则文本不会被截断,也就不会触发提示。 - 导入方式:从
@opentiny/vue-directive包中导入AutoTip,注册为局部指令即可。 - Composition API 注意:在
<script setup>中,需要将AutoTip赋值给一个变量(如VAutoTip),Vue 3 的 setup 语法糖会自动将以V开头的变量识别为指令。
三、进阶用法:自定义提示内容
基本用法已经能覆盖 80% 的场景,但有些时候你需要更多控制。v-auto-tip 可以接收一个指令参数,类型为对象,支持以下属性:
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
always | boolean | false | 是否始终显示 tooltip。true 时无论文本是否超长都显示,false 时仅超长时显示 |
content | string | VNode | VNode[] | — | 提示的内容。不传则使用当前 DOM 元素的文本内容;支持传入字符串、VNode 或 VNode 数组 |
effect | string | 'light' | 提示主题效果,支持 'light' 和 'dark' |
placement | string | 'top' | 提示弹出位置,与 Tooltip 组件的 placement 属性一致 |
popperClass | string | — | 弹出层的自定义 class(3.28 版本引入) |
另外,如果指令参数直接传 false,则禁止自动提示,相当于一个动态开关。
实战示例:待办事项列表
来看一个真实场景——待办事项列表,部分项目被禁用,需要显示禁用原因:
<template>
<div>
<div class="title">待办事项:</div>
<div
v-for="item in options"
:key="item.title"
:class="{
is_disabled: item.disabled,
list: true
}"
v-auto-tip="item.disabled ? { always: true, content: item.disabledReason, effect: 'dark' } : false"
>
{{ item.text }}
</div>
</div>
</template>
<script lang="jsx">
import { AutoTip } from '@opentiny/vue-directive'
export default {
directives: { AutoTip },
data() {
return {
options: [
{ text: '去游泳馆游泳', disabled: false },
{ text: '去羽毛球馆打羽毛球', disabled: true, disabledReason: '羽毛球拍坏了' },
{
text: '去爬山/海边沙滩',
disabled: true,
disabledReason: (
<span>
还没有选择项目,现在去
<a href="javascript:void(0)" style="color:#f80">
选择
</a>
</span>
)
}
]
}
}
}
</script>
<style scoped>
.title {
font-size: 16px;
font-weight: bolder;
margin-bottom: 20px;
}
.list {
width: 260px;
height: 30px;
line-height: 30px;
border-bottom: 1px solid #ccc;
margin-top: 10px;
}
.is_disabled {
cursor: not-allowed;
text-decoration: line-through;
}
</style>
这个示例的精妙之处
- 动态开关:
v-auto-tip="item.disabled ? {...} : false"——不禁用的项目传false完全关闭提示,禁用的项目传配置对象开启提示。一行表达式搞定条件逻辑。 always: true的妙用:禁用项的文字可能并不超长,但我们仍然希望鼠标移入时显示禁用原因。always: true让 tooltip 无视文本长度,始终弹出。content支持 VNode:第三个待办项的禁用原因不是普通字符串,而是一个带超链接的 JSX VNode。这意味着你可以在 tooltip 里放任何自定义内容——链接、按钮、甚至小表单,想象力就是极限。
Composition API 版本同理:
<script setup lang="jsx">
import { AutoTip } from '@opentiny/vue-directive'
const VAutoTip = AutoTip
const options = [
{ text: '去游泳馆游泳', disabled: false },
{ text: '去羽毛球馆打羽毛球', disabled: true, disabledReason: '羽毛球拍坏了' },
{
text: '去爬山/海边沙滩',
disabled: true,
disabledReason: (
<span>
还没有选择项目,现在去{' '}
<a href="javascript:void(0)" style="color:#f80">
选择
</a>
</span>
)
}
]
</script>
四、API 速查表
| 指令用法 | 说明 |
|---|---|
v-auto-tip | 无参数,自动探测文本超长时显示 tooltip |
v-auto-tip="{ always: true, content: '自定义内容' }" | 传入配置对象 |
v-auto-tip="false" | 禁止自动提示 |
配置对象属性一览
| 属性 | 类型 | 默认值 | 说明 |
|---|---|---|---|
always | boolean | false | true = 无论是否超长都显示;false = 仅超长时显示 |
content | string | VNode | VNode[] | 当前元素文本 | 自定义提示内容,支持 JSX |
effect | 'light' | 'dark' | 'light' | tooltip 主题 |
placement | string | 'top' | 弹出位置,同 Tooltip 的 placement |
popperClass | string | — | 弹出层自定义 class |
五、最佳实践建议
- 别忘了溢出样式:
v-auto-tip只探测不截断。确保目标元素有overflow: hidden; text-overflow: ellipsis; white-space: nowrap;(或其他溢出隐藏方案)。 - 优先用无参数形式:大多数场景下,直接
v-auto-tip就够了,不需要过度配置。 - 动态场景用三元表达式:
v-auto-tip="condition ? { always: true, content: msg } : false"是处理条件提示的最佳模式。 - 复杂提示用 JSX VNode:当提示内容需要包含链接、按钮等交互元素时,
content属性配合 JSX 可以实现富文本提示。 - 性能无忧:
v-auto-tip的探测逻辑仅在鼠标移入时触发,不会造成额外的渲染开销。
六、总结
v-auto-tip 是 TinyVue 指令体系中一个看似简单却极其实用的工具。它把"文本溢出检测 + tooltip 展示"这个高频需求封装成一行指令,让开发者从手动判断、手动包裹的泥潭中解放出来。
- 简单场景:一行
v-auto-tip,零配置,开箱即用 - 复杂场景:配置对象 + JSX VNode,提示内容随心定制
- 动态场景:三元表达式 +
false开关,灵活控制
下次再遇到文本溢出提示的需求,别再手动包 tooltip 了——试试 v-auto-tip,一行代码的事。