142 lines
3.2 KiB
Vue
142 lines
3.2 KiB
Vue
|
|
<template>
|
||
|
|
<a-tooltip :disabled="isShowBtn || (!isShowBtn && disabled)" :placement="props.placement">
|
||
|
|
<template #content>
|
||
|
|
<div :style="contentStyle" class="tip-content">{{ props.context }}</div>
|
||
|
|
</template>
|
||
|
|
<div class="overflow-hidden">
|
||
|
|
<div v-bind="$attrs" ref="Text" :class="`${isShow ? '' : `line-${props.line}`} `" class="overflow-text">
|
||
|
|
{{ props.context }}
|
||
|
|
</div>
|
||
|
|
<div
|
||
|
|
v-if="isShowBtn && !disabled"
|
||
|
|
class="color-#8C8C8C flex items-center cursor-pointer mt-2px"
|
||
|
|
@click="
|
||
|
|
() => {
|
||
|
|
isShow = !isShow;
|
||
|
|
}
|
||
|
|
"
|
||
|
|
>
|
||
|
|
{{ isShow ? '收起' : '展开' }}
|
||
|
|
<icon-up size="16" :class="{ active: isShow }" class="ml-2px color-#8C8C8C" />
|
||
|
|
</div>
|
||
|
|
</div>
|
||
|
|
</a-tooltip>
|
||
|
|
</template>
|
||
|
|
|
||
|
|
<script setup>
|
||
|
|
import { ref, reactive, toRefs, onBeforeMount, onMounted, watchEffect, computed, watch, nextTick, defineProps } from 'vue';
|
||
|
|
import elementResizeDetectorMaker from 'element-resize-detector';
|
||
|
|
|
||
|
|
const props = defineProps({
|
||
|
|
context: {
|
||
|
|
type: String,
|
||
|
|
default: '',
|
||
|
|
},
|
||
|
|
placement: {
|
||
|
|
type: String,
|
||
|
|
default: 'bottom',
|
||
|
|
},
|
||
|
|
line: {
|
||
|
|
type: Number,
|
||
|
|
default: 1,
|
||
|
|
},
|
||
|
|
maxHeight: {
|
||
|
|
type: [String, Number],
|
||
|
|
default: '',
|
||
|
|
},
|
||
|
|
maxWidth: {
|
||
|
|
type: [String, Number],
|
||
|
|
default: '',
|
||
|
|
},
|
||
|
|
isShowBtn: {
|
||
|
|
type: Boolean,
|
||
|
|
default: false,
|
||
|
|
},
|
||
|
|
});
|
||
|
|
|
||
|
|
const data = reactive({});
|
||
|
|
const isShow = ref(false);
|
||
|
|
const contentStyle = computed(() => {
|
||
|
|
let style = {
|
||
|
|
'max-height': props.maxHeight + 'px',
|
||
|
|
'max-width': props.maxWidth + 'px',
|
||
|
|
overflow: 'auto',
|
||
|
|
padding: '1px 0',
|
||
|
|
};
|
||
|
|
return props.maxHeight || props.maxWidth ? style : {};
|
||
|
|
});
|
||
|
|
const disabled = ref(true);
|
||
|
|
const Text = ref(null);
|
||
|
|
const textWidth = ref();
|
||
|
|
watch(
|
||
|
|
[() => props.context, textWidth],
|
||
|
|
async () => {
|
||
|
|
if (props.context) {
|
||
|
|
await nextTick();
|
||
|
|
nextTick(() => {
|
||
|
|
if (props.line < 2) {
|
||
|
|
if (Text.value?.clientWidth < Text.value?.scrollWidth) {
|
||
|
|
disabled.value = false;
|
||
|
|
} else {
|
||
|
|
disabled.value = true;
|
||
|
|
}
|
||
|
|
} else {
|
||
|
|
if (Text.value?.clientHeight < Text.value?.scrollHeight) {
|
||
|
|
disabled.value = false;
|
||
|
|
} else {
|
||
|
|
disabled.value = true;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
});
|
||
|
|
}
|
||
|
|
},
|
||
|
|
{
|
||
|
|
deep: true,
|
||
|
|
immediate: true,
|
||
|
|
},
|
||
|
|
);
|
||
|
|
onBeforeMount(() => {});
|
||
|
|
onMounted(async () => {
|
||
|
|
await nextTick();
|
||
|
|
const erd = elementResizeDetectorMaker();
|
||
|
|
if (Text.value) {
|
||
|
|
erd.listenTo(Text.value, () => {
|
||
|
|
const _width = Text.value.getBoundingClientRect().width;
|
||
|
|
textWidth.value = _width;
|
||
|
|
});
|
||
|
|
}
|
||
|
|
});
|
||
|
|
watchEffect(() => {});
|
||
|
|
defineExpose({
|
||
|
|
...toRefs(data),
|
||
|
|
});
|
||
|
|
</script>
|
||
|
|
<style scoped lang="scss">
|
||
|
|
.overflow-text {
|
||
|
|
display: inline-block;
|
||
|
|
font-family: $font-family-regular;
|
||
|
|
width: 100%;
|
||
|
|
vertical-align: middle;
|
||
|
|
font-style: normal;
|
||
|
|
box-sizing: border-box;
|
||
|
|
white-space: pre-line;
|
||
|
|
&.line-1 {
|
||
|
|
overflow: hidden;
|
||
|
|
text-overflow: ellipsis;
|
||
|
|
white-space: nowrap;
|
||
|
|
}
|
||
|
|
&.line-2 {
|
||
|
|
@include multi-ellipsis(2);
|
||
|
|
}
|
||
|
|
&.line-3 {
|
||
|
|
@include multi-ellipsis(3);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
.tip-content {
|
||
|
|
white-space: pre-line;
|
||
|
|
}
|
||
|
|
.active {
|
||
|
|
transform: rotate(-180deg);
|
||
|
|
}
|
||
|
|
</style>
|