功能:这段代码是一个Vue组件,主要用于处理文本溢出的问题。当文本长度超过其容器宽度时,它会显示一个带有工具提示的文本,当鼠标悬停在文本上时,工具提示会显示完整的文本。
目的:防止文本溢出其容器,提升用户体验。
使用场景:这个组件可以用在任何需要显示文本的地方,特别是在文本长度可能超过其容器宽度的情况下。
主要逻辑:
- 在模板中,使用了Vue的v-if指令来判断文本是否溢出。如果溢出,则显示一个带有工具提示的文本;如果没有溢出,则直接显示文本。
- 在脚本中,首先定义了一些props,包括文本内容和字体大小。然后在mounted钩子函数中,检查文本是否溢出。
- 检查文本溢出的逻辑是:首先,创建一个测量容器,将文本放入测量容器,然后获取文本的宽度。如果文本的宽度大于容器的宽度,则认为文本溢出。
- 在样式中,为文本设置了overflow: hidden,white-space: nowrap和text-overflow: ellipsis,这样当文本溢出时,会显示省略号。
JS获取字符串长度的几种常用方法
-
通过创建一个不会在页面显示出来的dom元素,然后把文本内容设置进去,真实的文本长度与标题盒子比较宽度,判断是否被溢出隐藏了,这种方式会导致性能问题,特别是在表格的时候,创建DOM和删除DOM
-
使用canvas中的measureText方法和TextMetrics对象来获取元素的宽度
通过Canvas 2D渲染上下文(context)可以调用measureText方法,此方法会返回TextMetrics对象,该对象的
width
属性值就是字符占据的宽度,由此也能获取到文本的真实宽度,此方法有弊端,比如说兼容性,精确度等等。
<template>
<!-- 当文本溢出时,显示提示信息 -->
<a-tooltip
arrowPointAtCenter
autoAdjustOverflow
overlayClassName="text-overflow"
v-if="isOverflow"
:title="text"
>
<div
class="text-overflow"
ref="textContainer"
>
{{ text }}
</div>
</a-tooltip>
<!-- 当文本未溢出时,直接显示文本 -->
<div
v-else
ref="textContainer"
>
{{ text || '--' }}
</div>
</template>
<script lang="ts" setup>
// 定义组件属性
const props = defineProps({
text: {
type: [String, Number],
default: '',
},
fontSize: {
type: [String, Number],
default: 14,
},
});
// 创建引用
const textContainer = ref();
const isOverflow = ref(false);
// 组件挂载后检查文本是否溢出
onMounted(async () => {
await nextTick();
checkOverflow();
});
// 检查文本是否溢出
const checkOverflow = () => {
if (textContainer.value) {
isOverflow.value = measureTextWidthWithCanvas() > textContainer.value.offsetWidth;
}
};
// 计算文本宽度 1.通过创建一个不会在页面显示出来的dom元素-这种方式通过创建dom和删除dom导致会有性能问题
const calculateTextWidth = () => {
// 创建一个测量容器
const container = document.createElement('div');
container.style.position = 'absolute';
container.style.visibility = 'hidden';
container.style.whiteSpace = 'nowrap';
document.body.appendChild(container);
// 将文本放入测量容器
container.textContent = String(props.text);
// 获取文本宽度
const width = container.offsetWidth;
// 移除测量容器
document.body.removeChild(container);
return width;
};
//2. 使用canvas测量文本宽度
function measureTextWidthWithCanvas() {
const canvas = document.createElement('canvas');
const context = canvas.getContext('2d') as CanvasRenderingContext2D;
context.font = `${props.fontSize}px PingFang SC`;
const metrics = context.measureText(String(props.text));
return metrics.width;
}
</script>
<style lang="less" scoped>
div {
width: 100%;
}
.text-overflow {
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
</style>
<style lang="less">
.text-overflow {
color: #000;
.ant-tooltip-content {
padding: 2px;
max-height: 350px;
overflow-y: auto;
background-color: rgba(0, 0, 0, 0.75);
border-radius: 4px;
box-shadow: 0 3px 6px -4px rgba(0, 0, 0, 0.12), 0 6px 16px 0 rgba(0, 0, 0, 0.08),
0 9px 28px 8px rgba(0, 0, 0, 0.05);
}
.ant-tooltip-inner {
white-space: break-spaces;
background-color: transparent;
box-shadow: none;
}
}
</style>