代码见文末
vue3实现
最开始就用的vue3实现,如下
vue2开发和使用文档
组件功能
TooltipText
是一个文字展示组件,具有以下功能:
- 文本显示:支持单行和多行文本显示。
- 自动判断溢出:判断文本是否溢出,根据溢出情况显示 tooltip。
- 自定义样式:可以通过
props
修改文本样式和 Tooltip 样式。 - 行数限制:支持多行文本显示,超出部分通过行数限制显示省略号。
使用方法
-
引入组件 将
TooltipText
注册到你的 Vue 项目中:import TooltipText from './TooltipText.vue'; export default { components: { TooltipText, }, };
-
组件模板示例
<template> <TooltipText :content="'这是一个演示文本。'" :lineClamp="2" :maxWidth="300" :tooltipOptions="{ placement: 'top', effect: 'light', trigger: 'hover', }" :outStyle="{ color: '#333', fontSize: '16px' }" /> </template>
-
传入参数
属性名 类型 默认值 说明 tooltipOptions
Object { content: 'Bottom center', placement: 'bottom', effect: 'dark', trigger: 'hover' }
Tooltip 的配置选项,参考 Element UI 的配置。 outStyle
Object { fontSize: '14px' }
外部样式对象,用于自定义文字样式。 content
String ''
显示的文本内容。 lineClamp
Number 1
显示的行数限制,超出部分会显示省略号。 maxWidth
Number 0
Tooltip 的最大宽度(单位 px)。 -
样式自定义 可通过
tooltipOptions
或outStyle
自定义 Tooltip 和文字样式::tooltipOptions="{ effect: 'light', placement: 'right', trigger: 'hover', }" :outStyle="{ fontSize: '18px', color: '#555' }"
-
动态内容 内容变动后会自动检查溢出并更新 Tooltip 显示状态,无需额外操作。
开发细节
-
溢出检查
- 单行文本通过
scrollWidth
和clientWidth
比较实现。 - 多行文本通过
scrollHeight
和clientHeight
比较实现。
- 单行文本通过
-
计算属性
computedMaxPopWidth
动态计算 Tooltip 的最大宽度,默认为文字容器宽度的 50%。computedIfWrap
判断是否为多行文本,根据lineClamp
属性动态更新。
-
监听与更新
- 使用
watch
监听content
的变动,在内容更新后重新计算溢出状态。
- 使用
-
样式
text-auto-nowrap
:单行文本样式,自动截断显示省略号。text-auto-wrap
:多行文本样式,支持行数限制。
注意事项
- 如果文本内容较长但设置了过小的
maxWidth
,可能导致 Tooltip 内容显示不全。 - 若需要动态调整文本或 Tooltip 样式,请确保
props
数据及时更新。
通过此组件可以轻松实现文本展示与溢出提示的功能,并满足多样化的样式需求。
<template>
<!-- Tooltip and text display container -->
<div>
<!-- Tooltip element from Element UI -->
<el-tooltip
v-bind="tooltipOptions" <!-- Bind tooltip options -->
:popper-class="!toolTipShow ? 'hide-tooltip tooltip-popper' : 'tooltip-popper'" <!-- Conditionally apply tooltip classes -->
>
<!-- Tooltip content slot -->
<template #content>
<div
class="tooltip-content"
:style="{ maxWidth: maxWidth || computedMaxPopWidth + 'px' }" <!-- Set maximum width for tooltip content -->
>
{{ content }} <!-- Display tooltip content -->
</div>
</template>
<!-- Text display with optional line clamp and styles -->
<div
:class="{ 'text-auto-wrap': computedIfWrap, 'text-auto-nowrap': !computedIfWrap }" <!-- Apply wrapping styles based on computed value -->
ref="textAutoRef" <!-- Reference for DOM access -->
:style="{
'-webkit-line-clamp': lineClamp, <!-- Apply line clamp for text -->
'line-clamp': lineClamp, <!-- Apply line clamp for text -->
...outStyle <!-- Merge additional styles -->
}"
>
{{ content }} <!-- Display main text content -->
</div>
</el-tooltip>
</div>
</template>
<script>
export default {
name: 'TooltipText',
props: {
// Tooltip options passed to Element UI el-tooltip
tooltipOptions: {
type: Object,
default: () => ({
content: 'Bottom center',
placement: 'bottom',
effect: 'dark',
trigger: 'hover',
}),
},
// Additional styles for the text container
outStyle: {
type: Object,
default: () => ({
fontSize: '14px',
}),
},
// Text content to display
content: {
type: String,
default: '',
},
// Number of lines to clamp text to
lineClamp: {
type: Number,
default: 1,
},
// Maximum width for tooltip content
maxWidth: {
type: Number,
default: 0,
},
},
data() {
return {
toolTipShow: false, // Whether to show the tooltip
textAutoRef: null, // Reference to the text container element
};
},
computed: {
// Compute the maximum width for the tooltip dynamically
computedMaxPopWidth() {
if (this.$refs.textAutoRef) {
return this.$refs.textAutoRef.clientWidth * 0.5; // Tooltip width is half of the text container width
}
return '100%'; // Default to full width if reference is not available
},
// Determine if text wrapping should be applied based on lineClamp
computedIfWrap() {
return this.lineClamp > 1;
},
},
watch: {
// Watch for changes in content and re-check overflow
content: {
handler() {
this.$nextTick(() => {
this.checkOverflow();
});
},
immediate: true,
},
},
methods: {
// Check if the text content overflows its container
checkOverflow() {
if (!this.$refs.textAutoRef) return;
if (!this.computedIfWrap) {
// Single-line text overflow check
this.toolTipShow = this.$refs.textAutoRef.scrollWidth > this.$refs.textAutoRef.clientWidth;
} else {
// Multi-line text overflow check
this.toolTipShow = this.$refs.textAutoRef.scrollHeight > this.$refs.textAutoRef.clientHeight;
}
},
},
mounted() {
// Perform overflow check after component is mounted
this.$nextTick(this.checkOverflow);
},
};
</script>
<style lang="scss" scoped>
.text-auto-nowrap {
width: 100%;
white-space: nowrap; <!-- Prevent text wrapping -->
overflow: hidden; <!-- Hide overflowing text -->
text-overflow: ellipsis; <!-- Show ellipsis for overflow -->
text-align: left; <!-- Align text to the left -->
}
.text-auto-wrap {
width: 100%;
text-align: left; <!-- Align text to the left -->
overflow: hidden; <!-- Hide overflowing text -->
text-overflow: ellipsis; <!-- Show ellipsis for overflow -->
display: -webkit-box; <!-- Use a flex container for wrapping -->
-webkit-box-orient: vertical; <!-- Set vertical orientation for line clamp -->
}
</style>
<style>
.hide-tooltip {
visibility: hidden !important; <!-- Hide the tooltip completely -->
}
</style>