Files
AgentCoord/frontend/src/components/MultiLineTooltip/index.vue

106 lines
2.2 KiB
Vue

<template>
<el-tooltip
:disabled="!isOverflow"
effect="light"
placement="top"
:content="text"
popper-class="multi-line-tooltip-popper"
>
<div
ref="containerRef"
class="multi-line-ellipsis"
:style="containerStyle"
@mouseenter="handleMouseEnter"
@mouseleave="handleMouseLeave"
>
<slot>
{{ text }}
</slot>
</div>
</el-tooltip>
</template>
<script lang="ts" setup>
import { computed, type HTMLAttributes, nextTick, onMounted, ref } from 'vue'
import { ElTooltip } from 'element-plus'
// 定义组件 props 类型
interface Props {
text?: string
lines?: number
maxWidth?: string | number
}
const props = withDefaults(defineProps<Props>(), {
text: '',
lines: 3,
maxWidth: '100%'
})
const isOverflow = ref(false)
const containerRef = ref<HTMLElement | null>(null)
// 计算容器样式
const containerStyle = computed(
() =>
({
maxWidth: props.maxWidth,
display: '-webkit-box',
WebkitBoxOrient: 'vertical',
WebkitLineClamp: props.lines,
overflow: 'hidden',
textOverflow: 'ellipsis',
lineHeight: '1.5',
wordBreak: 'break-all'
} as HTMLAttributes['style'])
)
// 检查文字是否溢出
const checkOverflow = (element: HTMLElement): boolean => {
// 单行情况下使用宽度判断
if (props.lines === 1) {
return element.scrollWidth > element.clientWidth
}
// 多行情况下使用高度判断
else {
return element.scrollHeight > element.clientHeight
}
}
// 鼠标进入处理
const handleMouseEnter = (event: MouseEvent) => {
const element = event.target as HTMLElement
console.log(checkOverflow(element))
isOverflow.value = checkOverflow(element)
}
// 鼠标离开处理
const handleMouseLeave = () => {
isOverflow.value = false
}
// 初始化时检查溢出状态
onMounted(() => {
nextTick(() => {
if (containerRef.value) {
isOverflow.value = checkOverflow(containerRef.value)
}
})
})
</script>
<style scoped>
.multi-line-ellipsis {
cursor: default;
overflow: hidden;
text-overflow: ellipsis;
white-space: normal;
}
</style>
<style>
.multi-line-tooltip-popper {
max-width: 400px;
}
</style>