🌈el-tooltip 文字溢出提示框显示,否则不显示

1,761 阅读3分钟

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 在进入目标元素及其子元素时都会触发。


🐝若本文章有错误或者不合理的地方,还请各位老师、同学指点!

👋结束~ 拜拜

lb04.jpg