通用悬停气泡:支持宽度、显示对齐方式修改
为解决使用表格、结构化表单等,因为字段过长默认悬停会占据整个屏幕宽度的情况,制作了通用组件悬停气泡以供使用,使用时记得关闭表格该字段默认悬停。
为解决遇见长乱码的问题情况,如输入的是各种字符包含><\等,该情况使用v-html可能出现后续字符无法显示的情况,引入了he库方法进行解决(npm install he)。
1、html页
template中:
html
<div
:class="['ellipsis-container', `ellipsis-container-${align}`]"
:id="`container-${idKey}`"
@mouseenter="checkOverflow"
@mouseleave="showTooltip = false"
>
<el-popover
:content="content ? he?.decode(content) : content"
:placement="placement"
:disabled ="!showTooltip"
:popper-style=" maxWidth:`${tooltipWidth}`, width:'auto'"
:popper-class="container-popover"
:effect="dark"
>
<template #reference>
<div ref="textRef" class="origin-content">
{{ content ? he?.decode(content) : content }} //为空情况不解码
</div>
</template>
<div class="pop-content">
{{ content ? he?.decode(content) : content }} //为空情况不解码
</div>
</el-popover>
</div>
2、js页
script setup中:
javascript
import { ref } from 'vue';
import he from 'he'; //引入防止长乱码无法显示的组件库 npm i he
const props = defineProps({
idKey: { require: true,}, //防止同页面多次引用该通用组件导致无法区分
content: {type: String }, // 悬停弹窗显示内容
placement: { // 悬停位置
type:String,
default: 'top',
},
tooltipWidth: { // 悬停弹窗的宽度
type: Number,
default: 350,
},
align: { // 悬停弹窗显示内容对齐方式
type: String,
default: 'left',
},
})
const textRef = ref(null);
const showTooltip = ref(false);
//检测是否需要悬停显示
const checkOverflow = () => {
//如果超出div宽度就显示
if(textRef.value.scrollWidth > textRef.value.clientWidth) {
showTooltip.value = true;
}
}
3、css页
<style lang='scss'>中:
css
.container-popover {
padding:5px 11px !important;
min-width: 0 !important;
font-size:12px !important;
line-height:20px !important;
.pop-text {
line-break: anywhere;
word-break: break-all;
word-wrap: break-word;
white-space: pre-wrap;
}
}
<style lang='scss' scoped>中:
css
.ellipsis-container {
max-width: 100%;
height: 100%;
display:flex;
align-items:center;
.origin-text {
white-space: nowrap; //不换行
text-overflow: ellipsis; //省略
overflow: hidden; //不超出盒子
word-wrap: break-word; //单词或数字截断
display: inline-block; // span之类的转行内块
vertical-align: middle; // 若没垂直居中可加
max-width: 100%;
}
}
.ellipsis-container-center {
justify-content: center;
}
.ellipsis-container-left{
justify-content: flex-start;
}
.ellipsis-container-right{
justify-content: flex-end;
}