<script setup lang="ts">
|
import { h, onMounted, ref } from "vue";
|
import { type TippyOptions, type TippyContent, useTippy } from "vue-tippy";
|
|
defineOptions({
|
name: "ReText"
|
});
|
|
const props = defineProps({
|
// 行数
|
lineClamp: {
|
type: [String, Number]
|
},
|
tippyProps: {
|
type: Object as PropType<TippyOptions>,
|
default: () => ({})
|
}
|
});
|
|
const slots = defineSlots<{
|
content: () => TippyContent;
|
default: () => any;
|
}>();
|
|
const textRef = ref();
|
const tippyFunc = ref();
|
|
const isTextEllipsis = (el: HTMLElement) => {
|
if (!props.lineClamp) {
|
// 单行省略判断
|
return el.scrollWidth > el.clientWidth;
|
} else {
|
// 多行省略判断
|
return el.scrollHeight > el.clientHeight;
|
}
|
};
|
|
const getTippyProps = () => ({
|
content: h(slots.content || slots.default),
|
...props.tippyProps
|
});
|
|
function handleHover(event: MouseEvent) {
|
if (isTextEllipsis(event.target as HTMLElement)) {
|
tippyFunc.value.setProps(getTippyProps());
|
tippyFunc.value.enable();
|
} else {
|
tippyFunc.value.disable();
|
}
|
}
|
|
onMounted(() => {
|
tippyFunc.value = useTippy(textRef.value?.$el, getTippyProps());
|
});
|
</script>
|
|
<template>
|
<el-text
|
v-bind="{
|
truncated: !lineClamp,
|
lineClamp,
|
...$attrs
|
}"
|
ref="textRef"
|
@mouseover.self="handleHover"
|
>
|
<slot />
|
</el-text>
|
</template>
|