[Vue3+ElementPlus] The content is super wide to display ellipsis and tooltip bubble prompt

        Foreword: This component is currently used to display the numerical value in the large visualization screen, but it cannot be used for the scene display of complex content for the time being. Big guys are welcome to help improve it.

        Realization goal: Secondary encapsulation on the basis of the tooltip component of the ElementPlus library to realize writing content inside the component. When the content exceeds the width of the parent box of the component, hide the excess part of the component content, display the ellipsis and prompt the entire content through the tooltip.

        Show results:

 

Instructions:

<!-- 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>

        Code BUG: Anything written in the Tip component will be displayed in the bubble, including comments. So don't write comments inside components! !

         Component code:

<!-- 技术栈: 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>

Attach the css code of previous tooltip style modification

// 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;
}

Guess you like

Origin blog.csdn.net/weixin_67665876/article/details/129470174
Recommended