vue3通过ElementPlus的tooltip组件实现自定义指令文字提示

news2024/11/19 11:25:17

vue3自定义指令实现tooltip文字提示,通过ElementPlus的tooltip组件

  • 简介
    • 步骤1:定义指令tooltip
    • 步骤2:createTooltip函数
    • 步骤3:autoShowToolTip
    • 步骤4:注册指令
    • 步骤5:测试

简介

之前的项目中,有些文字比较长,不可能全部展示出来,就自己手写了个指令版本的tooltip,开始使用的显示方式,是自己在body中单独创建了个元素,然后监听鼠标事件,然后采用position:fixed的方式展示。
后来,想了下,打算借助ElementPlus的tooltip组件进行实现,只需要自己去判断内容是否超出展示的边界即可,于是便有了这篇文章。
在这里插入图片描述

步骤1:定义指令tooltip

/**
 * 指令 tooltip
 * 使用方式:<div v-tooltip></div>
 */
export const tooltip: Directive = {
  mounted: function (el: HTMLElement, binding: DirectiveBinding) {
    createTooltip(el, binding);
  },
  updated(el: HTMLElement, binding: DirectiveBinding) {
    createTooltip(el, binding);
  },
};

步骤2:createTooltip函数

autoShowToolTip在步骤3中

/**
 * 创建tooltip,这里采用element-plus的tooltip组件
 * @param el 
 * @param binding 
 */
const createTooltip = (el: any, binding: DirectiveBinding) => {
  /**
   * 判断是否显示tooltip
   * 如果传值为true,则显示tooltip
   * 否则,autoShowToolTip 自动判断是否显示tooltip
   */
  const isShow = binding.value || autoShowToolTip(el, binding);
  // 创建组件,显示tooltip
  if (isShow) {
    // 判断是否有根元素,存在,则移除
    const elRoot = document.querySelector("#_tooltip_root");
    if (elRoot) {
      elRoot.remove();
    }
    // 初始化 根元素
    el._tiproot = null;
    el._tipapp = null;
    const id = "_tooltip_root";
    const _tiproot = document.createElement("div");
    _tiproot.id = id;
    _tiproot.classList.add("_tiproot");
    // 通过createApp 创建实例组件
    const _tipapp = createApp(ElTooltip, {
      trigger: "hover",
      virtualRef: el,
      rawContent: true,
      placement: "top",
      virtualTriggering: true,
      content: el.innerHTML,
    });
    el._tiproot = _tiproot;
    el._tipapp = _tipapp;
    // body添加根元素
    document.body.appendChild(_tiproot);
    // 将新组件挂载到根元素
    if (_tipapp && _tiproot) {
      el._tipapp.mount("#" + id);
    }
  }
};

步骤3:autoShowToolTip

/**
 * 判断宽度和高度是否自动展示提示内容
 * @param el 
 * @param binding 
 * @returns 
 */
const autoShowToolTip = (el: any, binding: DirectiveBinding) => {
  /**
   * 通过创建range 获取元素内容的宽度和高度
   */
  const range = document.createRange();
  range.setStart(el, 0);
  if (el && el.childNodes.length) {
    range.setEnd(el, el.childNodes.length);
  }
  let rangeWidth = range.getBoundingClientRect().width;
  let rangeHeight = range.getBoundingClientRect().height;
  const offsetWidth = rangeWidth - Math.floor(rangeWidth);
  const offsetHeight = rangeHeight - Math.floor(rangeHeight);
  if (offsetWidth < 0.001) {
    rangeWidth = Math.floor(rangeWidth);
  }
  if (offsetHeight < 0.001) {
    rangeHeight = Math.floor(rangeHeight);
  }
  // 计算元素在页面中的宽度、高度
  const style: any = window.getComputedStyle(el, null);
  const maxWidth = parseInt(style["width"] || style["width"]) || 0;
  const maxHeight = parseInt(style["height"]);
  // 获取元素的padding
  const pLeft = style["padding-left"];
  const pRight = style["padding-left"];
  const pTop = style["padding-left"];
  const pBottom = style["padding-left"];
  // 计算最终宽度、高度
  const finalWidth = rangeWidth + parseInt(pLeft) + parseInt(pRight);
  const finalHeight = rangeHeight + parseInt(pTop) + parseInt(pBottom);
  console.log(finalWidth, maxWidth);
  console.log(finalHeight, maxHeight);
  if (finalWidth > maxWidth || finalHeight > maxHeight) {
    return true;
  }
  return false;
};

步骤4:注册指令

import { createApp } from 'vue'
import './style.css'
import App from './App.vue'
import ElementPlus from 'element-plus'
import 'element-plus/dist/index.css'
import { tooltip } from "./directive"
const app = createApp(App)
app.use(ElementPlus)
app.directive("tooltip", tooltip)
app.mount('#app')

步骤5:测试

<script setup lang="ts"></script>
<template>
   <ul>
    <div class="tip-text" >单行文本溢出展示</div>
    <li  v-tooltip class="line1">孩子们呵着冻得通红,像紫芽姜一般的小手,七八个一齐来塑雪罗汉。因为不成功,谁的父亲也来帮忙了。罗汉就塑得比孩子们高得多,虽然不过是上小下大的一堆,终于分不清是壶卢还是罗汉;然而很洁白,很明艳,以自身的滋润相粘结,整个地闪闪地生光。</li>
    <div class="tip-text" >多行文本溢出展示</div>
    <li v-tooltip class="line-multiple">孩子们呵着冻得通红,像紫芽姜一般的小手,七八个一齐来塑雪罗汉。因为不成功,谁的父亲也来帮忙了。罗汉就塑得比孩子们高得多,虽然不过是上小下大的一堆,终于分不清是壶卢还是罗汉;然而很洁白,很明艳,以自身的滋润相粘结,整个地闪闪地生光。</li>
   </ul>
</template>

<style scoped lang="css">
ul{
list-style: none;
list-style-type: none;
width: 1200px;
margin: 0 auto;
}
.tip-text{
  font-size: 30px;
  color: red;
  margin-top: 30px;
  margin-bottom: 10px;
}
/* 单行文本溢出展示 */
.line1{
  cursor: pointer;
  width: 400px;
  overflow: hidden;
  white-space: nowrap;
  text-overflow: ellipsis;
}
/* 多行文本溢出展示 */
.line-multiple{
  display: -webkit-box;
  width: 400px;
  cursor: pointer;
  -webkit-line-clamp: 2; /* 指定显示的行数 */
  -webkit-box-orient: vertical; /* 设置伸缩盒模型的子元素排列方向为垂直 */
  overflow: hidden;
  text-overflow: ellipsis;
}
</style>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1710170.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

基于springboot实现华府便利店信息管理系统项目【项目源码+论文说明】计算机毕业设计

基于springboot实现华府便利店信息管理系统演示 摘要 现代经济快节奏发展以及不断完善升级的信息化技术&#xff0c;让传统数据信息的管理升级为软件存储&#xff0c;归纳&#xff0c;集中处理数据信息的管理方式。本华府便利店信息管理系统就是在这样的大环境下诞生&#xff…

NXP i.MX8系列平台开发讲解 - 3.13 Linux 之Audio子系统(二)

专栏文章目录传送门&#xff1a;返回专栏目录 目录 1. Linux ALSA 内核框架 2. Linux ALSA 代码分析 2.1 声卡驱动初始化 2.2 声卡创建注册 2.3 PCM设备创建 3. ALSA ASoC 3.1 Machine 3.2 Platform 3.3 Codec 上一章节&#xff0c;对于Linux Audio子系统有了大概的了解…

做视频号小店遇到差评怎么处理?如何规避差

大家好&#xff0c;我是喷火龙。 大家在做店的时候应该都会遇到品退、中差评这些问题&#xff0c;这对我们的店铺影响还是非常大的&#xff0c;差评过多就会影响店铺的体验分&#xff0c;从而影响店铺的流量&#xff0c;还会间接的影响商品的转化率&#xff0c;如果太低的话&a…

@RequestBody注解

文章目录 RequestBody注解基本概念在postman里如何发送接收端带有RequestBody的请求&#xff1f; RequestBody注解 基本概念 扩展&#xff1a; http报文会包含四部分&#xff0c;第一部分是请求行&#xff0c;第二部分是请求头&#xff0c;第三部分是空行&#xff0c;第四部分…

示教编程操作QA

示教器的连接问题 Q1&#xff1a;示教器显示连接断开&#xff0c;该如何解决&#xff1f; A1&#xff1a;原因&#xff1a;示教器与控制器之间断开连接&#xff0c;需要调整控制器来解决该问题。解决方法1&#xff1a;重启控制器&#xff1b;解决方法2&#xff1a;将控制器与P…

Python: 使用pyotp实现OTP一次性密码验证

使用pyotp实现OTP一次性密码验证 OTP的基本原理 生成一个共享秘钥作为随机数的种子服务端通过种子计算出当前的密码客户端也通过相同的种子计算出当前的密码验证客户端生成的密码和服务端生成的密码是否匹配 服务端和客户端计算的方式一样 共享密钥 时间因子 算法 > 密…

XDebug配置几件教程,phpstorm实现http请求断点调试

写这篇的文章的初衷:网络上配置XDebug的文章有很多,XDebug也有官方的文档, PhpStorm也有官方的文档,为什么还要写那? 相信不少人,都有一种感觉,虽然教程很多,但是按教程走一遍,自己的确不能正常调试。 问题出在下面几个方面: 1. 对调试过程中,没有一定的认识,因此…

100个 Unity小游戏系列五 -Unity 抽奖游戏专题三老虎机游戏

一、演示效果 二、知识点讲解 2.1 布局 public void CreateItems(SlotsData[] slotsData){isInited false;slotsPrizeList new List<SlotsData>();for (int i 0; i < slotsData.Length; i){var item slotsData[i];slotsPrizeList.Add(item);}float bottomY -it…

探索Python的包与模块:构建项目的基石

新书上架~&#x1f447;全国包邮奥~ python实用小工具开发教程http://pythontoolsteach.com/3 欢迎关注我&#x1f446;&#xff0c;收藏下次不迷路┗|&#xff40;O′|┛ 嗷~~ 目录 一、模块与包的基础认知 1. 模块的定义与创建 2. 包的组织与管理 二、模块与包的进阶使用…

【分支控制(if-else判断)】单分支-双分支-多分支-嵌套分支

程序流程控制 在程序中, 程序运行的流程控制决定程序是如何执行的, 是我们必须掌握的, 主要有三大流程控制语句. 顺序控制 (简单)分支控制 (判断)循环控制 (循环) 一. 顺序控制 顺序控制介绍 程序从上到下逐行地执行, 中间没有任何判断和跳转. 顺序控制举例和注意事项 Java中…

AUS GLOBAL 与 UNICEF 联合国儿童基金会共同帮助叙利亚和土耳其地震受灾居民

2023年2月6日,土耳其东南部和叙利亚发生两次强烈地震和数十次余震,数以千计的儿童和家庭面临危机。 成千上万的房屋被毁,许多家庭被迫流离失所,而在一年中的这个时候,气温经常低于冰点,雪和冻雨很常见。许多学校、医院以及其他医疗和教育设施被地震破坏或摧毁,这对儿童造成了巨…

马斯克开启军备竞赛,xAI筹集60亿美元

大模型技术论文不断&#xff0c;每个月总会新增上千篇。本专栏精选论文重点解读&#xff0c;主题还是围绕着行业实践和工程量产。若在某个环节出现卡点&#xff0c;可以回到大模型必备腔调重新阅读。而最新科技&#xff08;Mamba&#xff0c;xLSTM,KAN&#xff09;则提供了大模…

蓝桥杯—SysTick中断精准定时实现闪烁灯

在嵌入式系统中&#xff0c;SysTick_Handler 是一个中断服务例程&#xff08;Interrupt Service Routine, ISR&#xff09;&#xff0c;用于处理 SysTick 定时器的中断。SysTick 定时器通常用于提供一个周期性的定时中断&#xff0c;可以用来实现延时或者周期性任务。 SysTick…

AWS联网和内容分发之Transit Gateway

将Amazon VPC、AWS账户和本地网络连接到一个网关中。AWS Transit Gateway通过中央枢纽连接Amazon虚拟私有云&#xff08;VPC&#xff09;和本地网络。此连接简化了您的网络&#xff0c;并且结束了复杂的对等关系。Transit Gateway充当高度可扩展的云路由器&#xff0c;每个新的…

HLS入门(Xilinx Vivado 2019.2)——点亮LED仿真

HLS入门——点亮LED仿真 一、HLS简介&#xff08;一&#xff09;什么是HLS&#xff1f;&#xff08;二&#xff09;HLS能做什么&#xff1f;&#xff08;三&#xff09;HLS的使用&#xff08;四&#xff09;HLS的优势&#xff08;五&#xff09;HLS与VHDL/Verilog编程技术的关系…

【机器学习】【深度学习】正则化(Regularization)

概念 正则化&#xff08;Regularization&#xff09;是在机器学习模型中避免过拟合的一种技术。它通过引入一个惩罚项&#xff08;即正则项&#xff09;来限制模型的复杂度&#xff0c;以此来提防模型过度依赖训练数据&#xff0c;捕获数据中的噪音信息而导致过拟合现象。简单…

企业营收分析难?搞定收入认领月底不加班!

在当今日益激烈的市场竞争中&#xff0c;企业的营收分析不仅是衡量经营成果的关键指标&#xff0c;更是指导企业未来发展的重要依据。然而&#xff0c;对于许多企业来说&#xff0c;营收分析的过程往往繁琐且耗时&#xff0c;尤其是月底结账时&#xff0c;大量的数据和复杂的计…

【机器学习300问】95、什么是KNN算法?它和K-means什么关系?

一、KNN算法的定义 KNN&#xff08;K-Nearest Neighbors&#xff09;算法&#xff0c;是一种简单而有效的监督学习方法。它既可以用在分类任务&#xff0c;也可用在回归任务中。KNN算法的核心思想&#xff1a;在特征空间中&#xff0c;如果有一个数据点周围的大多数邻居属于某个…

10. C++异步IO处理库和使用libevent实现高性能服务器

C比较有名的异步IO处理库 libevent 这个主要使用的是epoll。libevthplibuvlibev 我们主要介绍libevent。 libevent重要函数 event_base_new 这个可以对应于epoll_create也就是创建一个实例。还可以初始化libevent所有管理相关的代码。比如说所能用到的队列&#xff0c;栈&a…

OFDM 802.11a的FPGA实现:发射部分的最终实现

目录 1.摘要 2.最终实现的ModelSim仿真 3.Matlab仿真和MoselSim仿真进行对比 4.完整工程 1.摘要 本系统在Xilinx的zynq 7000系列FPGA芯片上实现了一个基于IEEE 802.11a协议的OFDM基带处理发射机的功能。本系统包含了整个发射机的所有功能&#xff0c;包括序列训练符号、Si…