
Vben EllipsisText 组件实战指南Vue3 文本截断、Tooltip 与展开/收起完整方案【免费下载链接】vue-vben-adminA modern vue admin panel built with Vue3, Shadcn UI, Vite, TypeScript, and Monorepo. Its fast!项目地址: https://gitcode.com/GitHub_Trending/vu/vue-vben-admin导读EllipsisText是 vue-vben-adminVben Admin基于 Vue 3 与 Shadcn UI 封装的长文本展示组件用于解决后台管理系统中长文本截断显示、悬停提示全文、点击展开/收起这一高频 UI 需求。它内置了单行/多行省略、智能 Tooltip、展开交互等能力开箱即用。阅读本文后你将掌握该组件全部 Props、事件与插槽的用法并理解其底层截断检测与 Tooltip 联动原理可直接在表格列、描述列表、卡片摘要等场景中落地。组件定位与引入方式EllipsisText是 Vben Admin 公共组件库vben/common-ui中的一员。组件源码位于 packages/effects/common-ui/src/components/ellipsis-text/ellipsis-text.vue并在 packages/effects/common-ui/src/components/index.ts 中统一导出export * from ./ellipsis-text内部由 ellipsis-text/index.ts 导出组件本身。在业务代码中直接按需引入即可script langts setup import { EllipsisText } from vben/common-ui; /script从源码结构看该组件并不依赖某个特定 UI 框架的 Button/Text 等基础控件而是基于组件库内的VbenTooltip来自vben-core/shadcn-ui与 VueUse 的useElementSize组合实现因此可在各子应用web-antd、web-naive、web-ele 等中通用。基本用法把文本放进默认插槽通过maxWidth限制可视宽度即可实现单行省略template EllipsisText :max-width500{{ text }}/EllipsisText /template这是最典型的场景一段很长的描述文本例如项目介绍、接口备注、用户签名在宽度受限的容器内默认截断为一行并显示省略号鼠标悬停时自动弹出 Tooltip 展示完整内容。对应的官方示例可参考 docs/src/demos/vben-ellipsis-text/line/index.vue。maxWidth支持数字自动换算为px与字符串两种形式见源码中的textMaxWidth计算属性const textMaxWidth computed(() { if (typeof props.maxWidth number) { return ${props.maxWidth}px; } return props.maxWidth; });Props 完整说明以下是当前版本以仓库源码 ellipsis-text.vue 为准支持的 Props 全表Prop说明类型默认值expand是否允许点击文本展开/收起全部内容booleanfalseline文本最大可见行数number1maxWidth文本区域最大宽度number \| string100%placementTooltip 弹出位置bottom \| left \| right \| toptoptooltip是否启用 TooltipbooleantruetooltipWhenEllipsis是否仅在文本真正被截断时才显示 TooltipbooleanfalseellipsisThreshold截断检测使用的像素差异阈值number3tooltipBackgroundColorTooltip 背景颜色优先级高于 overlayStylestringtooltipColorTooltip 文字颜色优先级高于 overlayStylestringtooltipFontSizeTooltip 字体大小单位 px优先级高于 overlayStylenumber14tooltipMaxWidthTooltip 内容最大宽度px不设置时内容宽度自动与展示文本宽度保持一致number不设置tooltipOverlayStyleTooltip 内容区域样式CSSProperties{ textAlign: justify }几个值得注意的取值细节line: 1时组件走单行截断逻辑Tailwind 的truncate类line 1时走多行截断逻辑-webkit-box-webkit-line-clamp样式定义在组件style module的ellipsisMultiLine中。ellipsisThreshold控制是否算作被截断的严格程度数值越大判断越严格见下文原理分析默认3像素可有效避免因字体渲染误差导致的误判。tooltipMaxWidth不传时组件会用useElementSize测量文本元素宽度并加24px作为 Tooltip 默认宽度见源码watchEffect中的eleWidth.value 24保证提示框与文本宽度协调。事件与插槽组件仅暴露一个事件事件说明类型expandChange展开状态变化时触发(isExpand: boolean) void典型用法是配合expand在展开/收起时同步业务状态例如记录某行详情是否被展开template EllipsisText :line2 expand expand-change(val) (expanded val) {{ text }} /EllipsisText /template插槽方面除默认插槽展示文本内容外还提供tooltip插槽用于自定义 Tooltip 内容插槽说明tooltip自定义 Tooltip 内容注意组件模板中tooltip插槽内部会再嵌套一层默认插槽slot nametooltipslot/slot/slot即若提供了tooltip插槽则用它作为提示内容否则回退为默认文本。底层原理截断检测与 Tooltip 联动这一部分深入源码实现帮助你理解各 Props 是如何协同工作的。核心逻辑集中在 ellipsis-text.vue 中。1. 截断检测checkEllipsis当开启tooltipWhenEllipsis时组件通过比较元素的实际渲染尺寸与可见尺寸来判断文本是否真的被截断了const widthDiff element.scrollWidth - element.clientWidth; const heightDiff element.scrollHeight - element.clientHeight; isEllipsis.value props.line 1 ? widthDiff props.ellipsisThreshold : heightDiff props.ellipsisThreshold;单行模式line 1比较scrollWidth与clientWidth横向溢出超过阈值即认为被截断多行模式line 1比较scrollHeight与clientHeight纵向溢出超过阈值即认为被截断空文本直接判定为未截断originalTrimmed为空时返回false。2. 动态监听尺寸与内容变化为了让自动判断是否显示 Tooltip在窗口缩放、数据更新后依然准确组件在onMounted阶段注册了ResizeObserver监听文本元素尺寸变化并在onUpdated钩子中随内容更新重新检测卸载时通过onBeforeUnmount断开观察器onMounted(() { if (typeof ResizeObserver ! undefined props.tooltipWhenEllipsis) { resizeObserver new ResizeObserver(() checkEllipsis()); if (ellipsis.value) resizeObserver.observe(ellipsis.value); } checkEllipsis(); });同时通过 VueUse 的useElementSize(ellipsis)实时取得文本宽度用于计算 Tooltip 默认最大宽度。3. Tooltip 的禁用策略Tooltip 并非总是显示源码中通过VbenTooltip的disabled属性实现三层控制:disabled !props.tooltip || isExpand || (props.tooltipWhenEllipsis !isEllipsis) 即满足以下任一条件时不显示 Tooltiptooltip设为false完全关闭提示当前处于展开状态isExpand文本已完整可见无需提示开启了tooltipWhenEllipsis且检测到文本未被截断isEllipsis false。4. 展开/收起交互点击行为由handleExpand触发仅当expand为true时生效function onExpand() { isExpand.value !isExpand.value; emit(expandChange, isExpand.value); if (props.tooltipWhenEllipsis) checkEllipsis(); }展开后-webkit-line-clamp被清空isExpand ? : line文本完整显示此时 Tooltip 因isExpand为真而自动禁用避免已展开还弹提示的重复体验。视觉上开启expand后文本元素会加上cursor-pointer否则为cursor-text。进阶场景四个官方 Demo 拆解仓库 docs/src/demos/vben-ellipsis-text 提供了四个覆盖主要能力的示例可直接对照使用。场景一固定宽度单行省略line/index.vue 展示了最长见的用法传入超长文本并设置:max-width500组件自动截断为一行悬停显示全文。适合表格备注列、列表摘要等场景。场景二多行截断 点击展开expand/index.vue 使用:line3 expand让文本最多显示三行点击后展开全部内容、再次点击收起同时可通过expandChange事件感知状态变化。适合卡片详情、富文本摘要等需要更多/收起交互的场景。场景三仅在截断时显示 Tooltipauto-display/index.vue 展示了tooltip-when-ellipsis的典型用法——同样一段文本分别以:line2和:line3展示行数不足以容纳时悬停出现提示而本身能完整显示时悬停不出现提示避免打扰用户。template EllipsisText :line2 :tooltip-when-ellipsistrue {{ text }} /EllipsisText EllipsisText :line3 :tooltip-when-ellipsistrue {{ text }} /EllipsisText /template场景四自定义 Tooltip 内容tooltip/index.vue 演示了tooltip插槽的用法文本仍然截断展示但悬停时弹出的是精心排版的自定义内容这里是一段歌词配合maxWidth限制展示宽度template EllipsisText :max-width240 住在我心里孤独的 孤独的海怪 痛苦之王 开始厌倦 深海的光 停滞的海浪 template #tooltip div styletext-align: center 《秦皇岛》br /住在我心里孤独的br /孤独的海怪 痛苦之王br /开始厌倦 深海的光 停滞的海浪 /div /template /EllipsisText /template该场景适合需要展示富文本提示换行、图文、链接的进阶需求配合tooltipOverlayStyle、tooltipBackgroundColor、tooltipColor、tooltipFontSize可进一步定制提示框外观。使用建议与注意事项默认行为tooltip默认为true即任何截断文本悬停都会显示完整内容若希望只在真正溢出时才提示请显式开启tooltipWhenEllipsis。阈值调优若发现短文本被误判为截断或已截断却不提示可微调ellipsisThreshold默认3。阈值越大判断越严格。宽度单位maxWidth传数字会被当作 px 处理传百分比字符串如100%可自适应容器宽度。样式优先级tooltipBackgroundColor、tooltipColor、tooltipFontSize三个独立 Props 的优先级高于tooltipOverlayStyle中的同名属性二者同时设置时以独立 Props 为准tooltipOverlayStyle最终还会被注入maxWidth与fontSize。多行截断兼容性多行模式依赖-webkit-line-clampWebKit 系浏览器与 Chrome、Edge 均支持在表格、描述组件等窄容器中配合maxWidth使用效果最佳。参考资料官方文档docs/src/en/components/common-ui/vben-ellipsis-text.md组件实现packages/effects/common-ui/src/components/ellipsis-text/ellipsis-text.vue组件导出packages/effects/common-ui/src/components/index.ts示例源码docs/src/demos/vben-ellipsis-text【免费下载链接】vue-vben-adminA modern vue admin panel built with Vue3, Shadcn UI, Vite, TypeScript, and Monorepo. Its fast!项目地址: https://gitcode.com/GitHub_Trending/vu/vue-vben-admin创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考