Files
Situation-Awareness-Platfor…/src/components/GText/index.vue
2025-03-12 18:41:20 +08:00

128 lines
2.6 KiB
Vue

<template>
<div
v-if="!showAllContent"
ref="textRef"
class="g-text"
:class="{ 'is-ellipse': finalConfig?.ellipse }"
:style="{ '-webkit-line-clamp': finalConfig?.line }"
>
<d-tooltip :position="position" :disabled="!content || !finalConfig?.tooltip" :content="content">
<slot></slot>
</d-tooltip>
<div v-if="finalConfig.showAll && !showAllContent && isOver" class="watch-all" @click="onShowAll">查看全部</div>
</div>
<div class="g-text-all" v-else-if="showAllContent && finalConfig.showAll">
<slot></slot>
</div>
</template>
<script lang="ts">
export default {
name: 'GText'
};
</script>
<script setup lang="ts">
import { ref, onUnmounted, computed } from 'vue';
import { useMutationObserver, useResizeObserver } from '@vueuse/core';
const props = withDefaults(defineProps<{
config?: {
ellipse?: boolean;
line?: number;
tooltip?: boolean;
showAll?: boolean;
},
position?: string[];
}>(), {
config: () => ({
ellipse: true,
line: 1,
tooltip: true,
showAll: false
}),
position: () => ['top']
});
const textRef = ref(null);
const isOver = ref(false);
const content = ref('');
const showAllContent = ref(false);
const onShowAll = () => {
showAllContent.value = true;
};
const finalConfig = computed(() => {
return Object.assign({}, {
ellipse: true,
line: 1,
tooltip: true,
showAll: false
}, props.config);
});
const checkTextRange = () => {
if (!textRef.value) return false;
isOver.value = textRef.value.scrollHeight > textRef.value.clientHeight;
if (isOver.value) {
content.value = textRef.value.innerText || '';
}
};
const { stop } = useMutationObserver(textRef, (mutations) => {
if (mutations[0]) {
checkTextRange();
}
}, {
attributes: true,
childList: true,
subtree: true,
characterData: true
});
const { stop: stop2 } = useResizeObserver(textRef, () => {
checkTextRange();
});
onUnmounted(() => {
stop();
stop2();
});
</script>
<style scoped lang="scss">
.g-text {
position: relative;
display: inline-block;
&.is-ellipse {
display: -webkit-box;
overflow: hidden;
text-overflow: ellipsis;
word-break: break-all;
-webkit-box-orient: vertical;
}
&-all {
display: inline-block;
word-break: break-all;
}
&:hover {
.watch-all {
display: block;
}
}
}
.watch-all {
position: absolute;
right: 0;
bottom: 0;
z-index: 2;
background-color: var(--devui-global-bg, #f6f6f8);
padding: 2px 0 0 2px;
color: var(--color-CG600);
display: none;
&:hover {
cursor: pointer;
}
}
</style>