基于antDesign组件实现文字超出悬浮提示
<template>
<div ref="popTitle" :class="[popContainerClass, 'dsd-title-popover']" :style="popContainerStyle">
<a-popover v-if="visible" ref="popover" v-bind="popoverConfig" :title="title" v-model="popVisible"
:overlayStyle="overlayStyle">
<template #content>
<div class="popoverContent">
{{ content }}
</div>
</template>
<div ref="popTextContainer" :style="popTextStyle" class="dsd-pop-text cursor-pop">
<slot></slot>
</div>
</a-popover>
<div v-else ref="popTextContainer" :style="popTextStyle" class="dsd-pop-text">
<slot></slot>
</div>
</div>
</template>
<script setup lang="ts">
import { ref, reactive, onMounted, onUpdated, onBeforeUnmount, computed } from 'vue';
const popVisible = ref(false)
const resizeObs = ref()
const visible = ref(true)
const popTitle = ref()
const popTextContainer = ref()
const overlayStyle = reactive({
width: 'auto'
})
const props = defineProps({
// 最外围box class
popContainerClass: {
type: [String, Array],
default: null
},
// 最外围box style
popContainerStyle: {
type: Object,
default: () => {
}
},
// popover配置
popConfig: {
type: Object,
default: () => {
}
},
// 标题
title: {
type: String,
default: ''
},
// 内容
content: {
type: String,
default: ''
},
// 根据父节点定位
positionByParent: {
type: Boolean,
default: false
},
// 主题
theme: {
type: String,
default: 'lightTooltip' // darkTooltip | lightTooltip
},
// 定为节点
positionNode: {
type: Function,
default: () => {
}
},
// 悬浮框宽度,不指定默认与父节点同宽
overlayWidth: {
type: String,
default: ''
},
// 文字插槽样式
popTextStyle: {
type: Object,
default: () => {
}
}
})
onMounted(() => {
const resizeObserver = new ResizeObserver(() => {
sizeUpdate()
})
resizeObserver.observe(popTitle.value)
resizeObs.value = resizeObserver
})
onUpdated(() => {
sizeUpdate()
})
const popoverConfig = computed(() => {
let config = props.popConfig
config.overlayClassName = config.overlayClassName + ' ' + (props.theme === 'darkTooltip' ? props.theme : 'lightTooltip')
return {
...config,
getPopupContainer: (el) => getPopupContainer(el)
}
})
const sizeUpdate = () => {
visible.value = popTextContainer.value.offsetWidth < popTextContainer.value.scrollWidth
// 悬浮宽度不超过节点
if (!props.overlayWidth.length) {
overlayStyle.width = popTextContainer.value.offsetWidth + 'px'
} else if (props.overlayWidth === 'auto') {
overlayStyle.width = 'auto'
} else {
overlayStyle.width = props.overlayWidth
}
}
const getPopupContainer = (el) => {
let positionNode = null
if (!!props.positionNode(popTitle.value)) {
positionNode = props.positionNode(popTitle.value)
} else {
positionNode = props.positionByParent ? el.parentNode : document.querySelector('#dsdApp')
}
return positionNode
}
onBeforeUnmount(() => {
resizeObs.value.unobserve(popTitle.value)
})
</script>
<style lang="less" scoped>
.dsd-pop-text {
// 防止文字溢出显示省略号与原本宽度一直导致tooltip不显示
// width: 100.4%;
// width: 100%;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
line-height: 17px;
}
.cursor-pop {
cursor: pointer;
}
.popoverContent {
word-break: break-all;
}
:deep(.dsd-popover) {
.dsd-popover-inner-content,
.dsd-popover-inner {
border-radius: 2px;
}
}
</style>
<style lang="less">
.darkTooltip {
.dsd-popover-content {
.dsd-popover-arrow-content {
background: rgba(0, 0, 0, 0.7);
}
.dsd-popover-inner-content {
background: rgba(0, 0, 0, 0.7);
color: #fff;
}
}
}
</style>
评论
匿名评论
隐私政策
你无需删除空行,直接评论以获取最佳展示效果