【Vue3+ElementPlus】内容超宽显示省略号并tooltip气泡提示

        前言:该组件现用于可视化大屏中数值部分的展示,暂无法用于复杂内容的场景展示,欢迎大佬们帮忙改进。

        实现目标:在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;
}

猜你喜欢

转载自blog.csdn.net/weixin_67665876/article/details/129470174