前言:该组件现用于可视化大屏中数值部分的展示,暂无法用于复杂内容的场景展示,欢迎大佬们帮忙改进。
实现目标:在ElementPlus库tooltip组件的基础上二次封装,实现在组件内部书写内容,内容超出组件的父盒子宽度时,隐藏组件内容的超出部分,显示省略号并通过tooltip提示全部内容。
效果展示:
使用方法:
<!-- template部分 -->
<template>
<div class="box">
<Tip>
<b class="gray">{
{ 123456 }}</b>
</Tip>
</div>
</template>
// script部分
<script setup lang="ts">
import Tip from "@/components/..书写自己的文件夹路径../Tip.vue"
</script>
// css部分
<style scoped lang="scss">
.box {
width: 100px;
background-color: red;
}
</style>
代码BUG:在Tip组件中书写的任何内容都会展示在气泡中,包括注释。所以不要在组件内部书写注释!!
组件代码:
<!-- 技术栈: Vue3 + ElementPlus -->
<!-- 利用el-tooltip实现文字超出时显示省略号并气泡提示,否则不气泡提示 -->
<!-- 使用: Tip组件"内"必须包裹仅且一个html标签,外层div标签需要具有宽度
<div>
<Tip><templat>...</templat></Tip>
</div>
-->
<template>
<div v-if="flag">
<el-tooltip placement="top">
<template #content>{
{ content.join("") }}</template>
<div
class="ellipsis"
ref="slotRef">
<slot></slot>
</div>
</el-tooltip>
</div>
<div
v-else
class="ellipsis"
ref="slotRef">
<slot></slot>
</div>
</template>
<script setup lang="ts">
import { useSlots, ref, onMounted, onUpdated } from "vue";
const slots = useSlots() as any;
let slotDom = slots.default();
const slotRef = ref();
const flag = ref(false);
const content = ref([]);
const isArray = (arr: any) => {
return Object.prototype.toString.call(arr) === "[object Array]";
};
const childrenIsArray = (arr: any, content: Array<string>) => {
arr.forEach((v: any) => {
if (isArray(v.children)) {
childrenIsArray(v.children, content);
} else {
content.push(v.children);
}
});
};
const slotDomIsSingleElArray = (slotDom: any) => {
if (isArray(slotDom.children)) {
childrenIsArray(slotDom.children, content.value);
} else {
content.value = slotDom.children;
}
};
const getContent = () => {
if (slotDom.length > 1) {
slotDom.forEach((v: any, i: number) => {
slotDomIsSingleElArray(v);
});
} else {
slotDomIsSingleElArray(slotDom[0]);
}
};
const compareWidth = () => {
content.value = [];
const parentW = slotRef.value.offsetWidth;
const childW = slotRef.value.firstElementChild.offsetWidth;
childW > parentW ? (flag.value = true) : (flag.value = false);
if (flag.value) {
getContent();
}
};
onMounted(() => {
compareWidth();
});
onUpdated(() => {
slotDom = slots.default();
compareWidth();
});
</script>
<style lang="scss" scoped>
.ellipsis {
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
</style>
附往期tooltip样式修改的css代码
// tooltips 自定义样式
.el-popper.is-customized {
max-width: 400px !important;
padding: 6px 12px !important;
background: linear-gradient(180deg, #4574AB, #4574AB) !important;
}
.el-popper.is-customized .el-popper__arrow::before {
background: linear-gradient(45deg, #4574AB, #4574AB) !important;
right: 0;
}
// tooltips 默认样式
.el-popper.is-dark {
max-width: 400px !important;
padding: 6px 12px !important;
color: #fff;
border: 0px;
background: linear-gradient(180deg, #4574AB, #4574AB) !important;
}
.el-popper.is-dark .el-popper__arrow::before {
border: 0px;
background: linear-gradient(45deg, #4574AB, #4574AB) !important;
right: 0;
}