el-tooltip 文字溢出提示框显示,否则不显示
1.简介
2.代码部分
3.逻辑部分
4.核心思路
5.重点说明
👤简介
接上篇文章,是解决了某元素全屏状态下 tooltip组件提示框不显示问题,这次说一下tooltip组件 文字溢出出现提示框,否则不出现问题;
✍创作不易;如本文章帮助到了您,请给我一个👍吧;
其实该需求跟上次说的某元素全屏状态下 tooltip组件提示框不显示问题 问题,解决方法差不多;废话不多说,直接上代码;
🤖 代码部分
<div class="rBtmL_">
<div class="personBox_" v-for="(value, key, index) in dataLeft" :key="key">
<div class="personIcon_">
<img :src="dataLeft[key].icon" alt="">
</div>
<div class="contentPerson_" ref="contentPerson">
<el-tooltip :disabled="!isShowTooltip[index]" ref="myTooltip" :append-to-body="false" class="item" effect="dark" :content="computedContent(formData[value.value])" placement="top">
<span ref="content" @mouseenter="toggleTooltip(index)" v-if="formData[value.value]" class="ellipsis_">{{formData[value.value] }}</span>
<span v-else style="font-size: 14px;color: #ccc;">暂无数据</span>
</el-tooltip>
</div>
<div class="personKey_"> {{ key }} </div>
</div>
</div>
......
import {tooMixin} from 'path:xxx'// 这里是用的 mixins;因为多个相同组件逻辑一致;
export default {
mixins: [tooMixin]//注册
...
}
核心
- 事件:@mouseenter="toggleTooltip(index)" 鼠标悬停;
🐾逻辑代码
export const tooMixin = {
data() {
return {
isShowTooltip: [] // 控制每个 el-tooltip 的显示状态,使用数组来保存多个 tooltip 的状态
};
},
methods: {
// 重写 content ,因为tooltip的content属性不能为 数字类型;
computedContent(val) {
if (val) {
return String(val);
}
return '暂无数据';
},
// 判断是否超出宽度
toggleTooltip(index) {
this.$nextTick(() => {
const parentElement = this.$refs.contentPerson[index]; // 获取对应的父元素
const contentElement = this.$refs.content[index]; // 获取对应的内容元素
// 如果内容元素和父级元素都存在
if (contentElement && parentElement) {
const parentWidth = parentElement.offsetWidth;
const contentWidth = contentElement.offsetWidth;
// 判断内容宽度是否超出父级宽度,超出则显示 tooltip
this.$set(this.isShowTooltip, index, contentWidth >= parentWidth); // 更新对应的 tooltip 状态
// console.log(`内容宽度: ${contentWidth}, 父级宽度: ${parentWidth}, disabled: ${this.isShowTooltip[index]}`);
}
});
},
},
};
👀核心思路
首先的话,需要在 tooltip 文字展示的地方 加上鼠标悬停 事件;在该事件中 去获取 父级盒子的宽度和自身的内容的宽度,判断 父级和本身元素是否加载可以获取到,防止报错提示;
父级和自身元素都能获取到的情况下,就可以判断自身的内容宽度是否超出父级宽度了,超出则显示提示框,否则不显示;
然后根据判断的结果 更新对应的tooltip的状态;
最后 根据 <el-tooltip :disabled="!isShowTooltip[index]" ...>disabled去控制提示框的显示和隐藏;
🦀 全屏(非全屏)状态下 提示框根据内容显示/隐藏 + 全屏状态下 提示框不显示问题;
代码部分
<div class="rBtm_" ref="tooltipBox">
<div class="rBtmL_">
<div class="personBox_" v-for="(value, key, index) in dataLeft" :key="key">
<div class="personIcon_">
<img :src="dataLeft[key].icon" alt="">
</div>
<div class="contentPerson_" ref="contentPerson">
<el-tooltip :disabled="!isShowTooltip[index]" ref="myTooltip" :append-to-body="false" class="item" effect="dark"
:content="computedContent(formData[value.value])" placement="top">
<span ref="content" @mouseenter="toggleTooltip(index)" v-if="formData[value.value]" class="ellipsis_">{{formData[value.value] }}</span>
<span v-else style="font-size: 14px;color: #ccc;">暂无数据</span>
</el-tooltip>
</div>
<div class="personKey_"> {{ key }}</div>
</div>
</div>
<div class="rBtmR_">
<div class="rBtmR-item_" v-for="(value, key) in dataRight" :key="key">
<span class="itemKey_">{{ key }}</span>
<span class="itemValue_" v-if="formData[value]">{{ formData[value] }}</span>
<span v-else style="font-size: 14px;color: #ccc;">暂无数据</span>
</div>
</div>
</div>
逻辑部分
// path:src/utils/common.js
// 检查是否全屏
export function isFull () {
// 判断浏览器是否处于全屏状态 (需要考虑兼容问题)
// 火狐浏览器
let screenFull = document.mozFullScreen ||
document.fullScreen ||
// 谷歌浏览器及Webkit内核浏览器
document.webkitIsFullScreen ||
document.webkitRequestFullScreen ||
document.mozRequestFullScreen ||
document.msFullscreenEnabled
if (screenFull === undefined) {
screenFull = false
}
return screenFull
}
import { isFull } from '@/utils/common.js';
export const tooMixin = {
data() {
return {
isShowTooltip: [], // 控制每个 el-tooltip 的显示状态,使用数组来保存多个 tooltip 的状态
};
},
methods: {
// tooltip的content属性的值不能为 Number类型;
computedContent(val) {
if (val) {
return String(val);
}
return '暂无数据';
},
// 判断是否超出宽度
toggleTooltip(index) {
this.$nextTick(() => {
const parentElement = this.$refs.contentPerson[index]; // 获取对应的父元素
const contentElement = this.$refs.content[index]; // 获取对应的内容元素
// 如果内容元素和父级元素都存在
if (contentElement && parentElement) {
const parentWidth = parentElement.offsetWidth;
const contentWidth = contentElement.offsetWidth;
// 判断内容宽度是否超出父级宽度,超出则显示 tooltip
this.$set(this.isShowTooltip, index, contentWidth >= parentWidth); // 更新对应的 tooltip 状态
// console.log(`内容宽度: ${contentWidth}, 父级宽度: ${parentWidth}, disabled: ${this.isShowTooltip[index]}`);
}
// 如果全屏状态下,需要特殊处理
if (!checkFull()) return;
setTimeout(() => {
if (this.$refs.myTooltip) {
this.$refs.myTooltip.forEach((item) => {
this.$refs.tooltipBox.appendChild(item.popperVM.$el);
});
}
}, 100);
});
},
},
};
🚀 重点说明
@mouseenter 和 @mouseover 事件
简介:
@mouseenter 是 Vue.js 中用于监听鼠标进入元素时触发的 DOM 事件,它的作用等同于原生 JavaScript 中的 mouseenter 事件。
作用:
当用户的鼠标指针移动到某个元素上时,@mouseenter 事件会被触发,适用于需要在用户把鼠标移动到某个元素上时执行某些操作的场景,比如:
- 改变元素的样式(如悬停时改变颜色、大小等)
- 显示额外信息或工具提示
- 开始播放动画或执行其他交互行为
在 Vue.js 中,@mouseenter 通常用在模板中,绑定一个方法或内联表达式:
<template>
<div @mouseenter="handleMouseEnter">悬停我试试!</div>
</template>
<script>
export default {
methods: {
handleMouseEnter() {
console.log("鼠标进入了元素");
}
}
}
</script>
原理:
-
冒泡事件 :
mouseenter事件是不会冒泡的,它只会在目标元素上触发,不会冒泡到父元素身上;mouseenter只会在鼠标进入目标元素时触发,进入其子元素时不会重复触发。 -
mouseover在进入目标元素及其子元素时都会触发。元素传播。相比于mouseover事件,它不会在进入子元素时重复触发。因此,mouseenter更适合用于处理复杂的嵌套结构中的鼠标进入事件。 -
浏览器支持:
mouseenter是由浏览器原生支持的事件,和其他鼠标事件一样,它依赖于浏览器的事件模型进行触发。
@mouseenter 和 @mouseover 的区别:
-
mouseenter只会在鼠标进入目标元素时触发,进入其子元素时不会重复触发。 -
mouseover在进入目标元素及其子元素时都会触发。
🐝若本文章有错误或者不合理的地方,还请各位老师、同学指点!
👋结束~ 拜拜