<script setup lang="ts">
import { ref, onMounted, nextTick } from 'vue';
import { ElTooltip } from 'element-plus';
defineOptions({
name: 'TextOverflow',
});
interface Props {
/**
* è¦æ˜¾ç¤ºçš„æ–‡æœ¬å†…容
*/
text: string;
/**
* tooltip显示ä½ç½®
* @default 'top'
*/
tooltipPlacement?:
| 'top'
| 'top-start'
| 'top-end'
| 'bottom'
| 'bottom-start'
| 'bottom-end'
| 'left'
| 'left-start'
| 'left-end'
| 'right'
| 'right-start'
| 'right-end';
/**
* 是å¦å§‹ç»ˆæ˜¾ç¤ºtooltipï¼Œæ— è®ºæ˜¯å¦æº¢å‡º
* @default false
*/
alwaysShowTooltip?: boolean;
/**
* 自定义class
*/
class?: string;
/**
* 检测溢出的延迟时间(毫秒)
* @default 0
*/
checkDelay?: number;
}
const props = withDefaults(defineProps<Props>(), {
tooltipPlacement: 'top',
alwaysShowTooltip: false,
customClass: '',
checkDelay: 0,
});
const textRef = ref<HTMLElement | null>(null);
const isTextOverflow = ref(false);
/**
* æ£€æŸ¥æ–‡æœ¬æ˜¯å¦æº¢å‡º
*/
const checkTextOverflow = () => {
if (!textRef.value) return;
const element = textRef.value;
// 通过比较scrollWidthå’ŒclientWidthåˆ¤æ–æ˜¯å¦æº¢å‡º
isTextOverflow.value = element.scrollWidth > element.clientWidth;
};
/**
* åˆå§‹åŒ–æ—¶æ£€æŸ¥æ˜¯å¦æº¢å‡º
*/
onMounted(async () => {
// æ·»åŠ å»¶è¿Ÿï¼Œç¡®ä¿DOM已完全渲染
await nextTick();
if (props.checkDelay > 0) {
setTimeout(checkTextOverflow, props.checkDelay);
} else {
checkTextOverflow();
}
// 监å¬çª—å£å¤§å°å˜åŒ–ï¼Œé‡æ–°æ£€æµ‹æº¢å‡ºçжæ€
window.addEventListener('resize', checkTextOverflow);
});
/**
* åˆ¤æ–æ˜¯å¦éœ€è¦æ˜¾ç¤ºtooltip
*/
const shouldShowTooltip = () => {
return props.alwaysShowTooltip || isTextOverflow.value;
};
</script>
<template>
<div class="text-overflow-container" :class="props.class">
<ElTooltip
:content="props.text"
:disabled="!shouldShowTooltip()"
:placement="props.tooltipPlacement"
:enterable="false"
popper-class="text-overflow-tooltip"
>
<div ref="textRef" class="text-overflow-content">
{{ props.text }}
</div>
</ElTooltip>
</div>
</template>
<style lang="scss" scoped>
.text-overflow-container {
width: 100%;
display: inline-block;
}
.text-overflow-content {
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
:deep(.text-overflow-tooltip) {
max-width: 300px;
word-break: break-word;
}
</style>
|