128 lines
2.6 KiB
Vue
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>
|