基于Vue2.0仿Element UI的el-tooltip实现一个气泡框组件,支持多数据类型的显示和内容为空时不显示气泡框

简介: 该文章介绍了如何基于Vue2.0仿照Element UI的el-tooltip组件实现一个自定义的气泡框组件,该组件能够根据内容是否为空智能显示或隐藏,支持多种数据类型的显示。

场景:因为有个需求就是鼠标经过可多选的 el-select 选择器时,需要有个气泡框显示已选的内容,其实 el-tooltip 气泡框可以满足需求,就是用 el-tooltip 气泡框来包裹 el-select 选择器,但是当选择器一个也没选中,即内容为空时不应该也显示气泡框,有点影响美观。应该就是若内容为空时,气泡框可以直接不显示出来。

因此,通过网上查找相关案例,自行设计一个仿Element UI的气泡框el-tooltip组件,不过多多少少不及官方Element UI的气泡框 el-tooltip 组件,只是可以满足内容为空时不显示气泡框,也就不需要v-if来判断内容是否为空,频繁创建与销毁组件,以及避免带来的用户体验问题。同时,支持输入的内容为整型、字符串、数组等,会有各自的显示。

父组件:index.vue

<template>
  <div>
    <div style="width: 300px; height: 300px; margin: 300px 200px; padding: 20px; background-color: #eee;">

      <!-- 气泡框内容为空 -->
      <MagicPopover :content="''">
        <el-button size="mini">气泡框内容为空,直接不显示气泡框</el-button>
      </MagicPopover>

      <br /><br /><br />


      <!-- 气泡框内容为整型 -->
      <MagicPopover :content="content1">
        <el-button size="mini">气泡框内容为整型</el-button>
      </MagicPopover>

      <br /><br /><br />

      <!-- 气泡框内容为字符串 -->
      <MagicPopover :content="content2">
        <el-button size="mini">气泡框内容为字符串</el-button>
      </MagicPopover>

      <br /><br /><br />

      <!-- 气泡框内容为数组 -->
      <MagicPopover :content="content3">
        <el-button size="mini">气泡框内容为数组</el-button>
      </MagicPopover>
    </div>    
  </div>
</template>

<script>
import MagicPopover from "./components/magicPopover";

export default {
   
   
  components: {
   
   
    MagicPopover
  },
  data: () => ({
   
   
    content1: 5201314,
    content2: 'HelloWorld',
    content3: [5201314, 'HelloWorld']
  })
}
</script>

<style scoped>

</style>

子组件:magicPopover.vue

<template>
  <div
    class="esse-popover"
    @mouseenter="handleMouseEnterEvent"
    @mouseleave="handleMouseLeaveEvent"
  >
    <transition name="fade">
      <div
        class="esse-popover-wrapper"
        ref="essePopoverWrapperRef"
        v-if="isView && content != null && content != ''"
      >
        <!-- 判断是否为数组 -->
        <div v-if="(content instanceof Array)">
          <p v-for="(item, key) of content" :key="key">{
   
   {
   
    item }}</p>
        </div>

        <!-- 其他类型,包括字符串、整型、对象... -->
        <div v-else>
          <p>{
   
   {
   
    content }}</p>
        </div>
      </div>
    </transition>

    <div ref="essePopoverSlotRef">
      <slot></slot>
    </div>
  </div>
</template>

<script>
export default {
   
   
props: [
  'content'
],
data() {
   
   
  return {
   
   
    isView: false,
  }
},
methods: {
   
   
  /**
   * 鼠标进入事件
   */
  handleMouseEnterEvent(event) {
   
   
    this.isView = true;
    this.$nextTick(() => {
   
   
      this.draw();
    })
  },

  /**
   * 鼠标离开事件
   */
  handleMouseLeaveEvent(event) {
   
   
    this.isView = false;
  },

  /**
   * 渲染气泡框
   */
  draw() {
   
   
    if (this.content != null && this.content != '') {
   
   
      document.body.appendChild(this.$refs.essePopoverWrapperRef);
      let {
   
   left, top, width} = this.$refs.essePopoverSlotRef.getBoundingClientRect();
      // console.log('this.$refs.essePopoverSlotRef.getBoundingClientRect() =>', this.$refs.essePopoverSlotRef.getBoundingClientRect());
      const offsetTop = 10;// 偏移高度
      const offsetleft = width / 2;// 便宜位移,从左边计算
      this.$refs.essePopoverWrapperRef.style.top = top - offsetTop + 'px';
      this.$refs.essePopoverWrapperRef.style.left = left + offsetleft + 'px';
      document.styleSheets[0].addRule('.esse-popover-wrapper::before','display: block; left: 50%; bottom: 0');// 显示三角形伪类元素
    }
  },
},
}
</script>

<style scoped>
  .esse-popover {
   
   
    width: auto;
    display: inline-block;
    position: relative;
  }

  .esse-popover-wrapper {
   
   
    position: absolute;
    z-index: 99;
    width: 250px;
    height: auto;
    padding: 6px;
    border: 1px solid #ebeef5;
    box-shadow: 0 2px 12px 0 rgba(0, 0, 0, 0.2);
    background-color: #fff;
    transform: translate(-50%, -100%);
  }

  .esse-popover-wrapper p {
   
   
    margin: auto;
    font-size: 13px;
  }

  /* 使用伪元素创建小三角形 */
  .esse-popover-wrapper::before {
   
   
    content: "";
    position: absolute;
    border-width: 6px 6px 0 6px;
    border-style: solid;
    border-color: transparent;
    border-top-color: #fff;
    transform: translate(-50%, 100%);
  }
  /* / 使用伪元素创建小三角形 */

  /* 淡入淡出效果 */
  .fade-enter-active {
   
   
    /* transition: opacity 1s; */
    transition: all ease 1s;
  }
  .fade-leave-active {
   
   
    /* transition: opacity 0.3s; */
    transition: all ease 0.3s;
  }
  .fade-enter, .fade-leave-to /* .fade-leave-active, 2.1.8 版本以下 */ {
   
   
    opacity: 0;
  }
  /* / 淡入淡出效果 */
</style>

效果如下~

参考资料

Vue基础popover弹出框编写及bug问题分析 - 编程宝库

目录
相关文章
|
1天前
「Mac畅玩鸿蒙与硬件46」UI互动应用篇23 - 自定义天气预报组件
本篇将带你实现一个自定义天气预报组件。用户可以通过选择不同城市来获取相应的天气信息,页面会显示当前城市的天气图标、温度及天气描述。这一功能适合用于动态展示天气信息的小型应用。
60 38
「Mac畅玩鸿蒙与硬件46」UI互动应用篇23 - 自定义天气预报组件
|
28天前
|
前端开发 搜索推荐 开发者
「Mac畅玩鸿蒙与硬件20」鸿蒙UI组件篇10 - Canvas 组件自定义绘图
Canvas 组件在鸿蒙应用中用于绘制自定义图形,提供丰富的绘制功能和灵活的定制能力。通过 Canvas,可以创建矩形、圆形、路径、文本等基础图形,为鸿蒙应用增添个性化的视觉效果。本篇将介绍 Canvas 组件的基础操作,涵盖绘制矩形、圆形、路径和文本的实例。
63 12
「Mac畅玩鸿蒙与硬件20」鸿蒙UI组件篇10 - Canvas 组件自定义绘图
|
28天前
|
搜索推荐 前端开发 开发者
「Mac畅玩鸿蒙与硬件19」鸿蒙UI组件篇9 - 自定义动画实现
自定义动画让开发者可以设计更加个性化和复杂的动画效果,适合表现独特的界面元素。鸿蒙提供了丰富的工具,支持通过自定义路径和时间控制来创建复杂的动画运动。本篇将带你学习如何通过自定义动画实现更多样化的效果。
72 11
「Mac畅玩鸿蒙与硬件19」鸿蒙UI组件篇9 - 自定义动画实现
|
28天前
|
UED 开发者
「Mac畅玩鸿蒙与硬件18」鸿蒙UI组件篇8 - 高级动画效果与缓动控制
高级动画可以显著提升用户体验,为应用界面带来更流畅的视觉效果。本篇将深入介绍鸿蒙框架的高级动画,包括弹性动画、透明度渐变和旋转缩放组合动画等示例。
63 12
「Mac畅玩鸿蒙与硬件18」鸿蒙UI组件篇8 - 高级动画效果与缓动控制
|
24天前
|
UED
「Mac畅玩鸿蒙与硬件31」UI互动应用篇8 - 自定义评分星级组件
本篇将带你实现一个自定义评分星级组件,用户可以通过点击星星进行评分,并实时显示评分结果。为了让界面更具吸引力,我们还将添加一只小猫图片作为评分的背景装饰。
63 6
「Mac畅玩鸿蒙与硬件31」UI互动应用篇8 - 自定义评分星级组件
|
28天前
|
UED
「Mac畅玩鸿蒙与硬件17」鸿蒙UI组件篇7 - Animation 组件基础
在应用开发中,动画效果可以增强用户体验。鸿蒙框架提供了 translate、scale 和 rotate 等动画功能,允许对组件进行平移、缩放和旋转等操作。本篇将介绍 Animation 组件的基础知识和示例代码。
76 10
「Mac畅玩鸿蒙与硬件17」鸿蒙UI组件篇7 - Animation 组件基础
|
26天前
|
前端开发 开发者
「Mac畅玩鸿蒙与硬件21」鸿蒙UI组件篇11 - Canvas 组件的静态进阶应用
在鸿蒙应用开发中,Canvas 组件不仅用于基础绘图,还提供了处理复杂路径和渐变效果的多种手段,帮助开发者实现精美的静态图形。本篇将介绍如何在 Canvas 中绘制复杂路径、创建渐变填充效果。
44 7
「Mac畅玩鸿蒙与硬件21」鸿蒙UI组件篇11 - Canvas 组件的静态进阶应用
|
26天前
|
前端开发 开发者
「Mac畅玩鸿蒙与硬件22」鸿蒙UI组件篇12 - Canvas 组件的动态进阶应用
在鸿蒙应用中,Canvas 组件可以实现丰富的动态效果,适合用于动画和实时更新的场景。本篇将介绍如何在 Canvas 中实现动画循环、动态进度条、旋转和缩放动画,以及性能优化策略。
45 6
「Mac畅玩鸿蒙与硬件22」鸿蒙UI组件篇12 - Canvas 组件的动态进阶应用
|
26天前
|
前端开发 开发者
「Mac畅玩鸿蒙与硬件23」鸿蒙UI组件篇13 - 自定义组件的创建与使用
自定义组件可以帮助开发者实现复用性强、逻辑清晰的界面模块。通过自定义组件,鸿蒙应用能够提高代码的可维护性,并简化复杂布局的构建。本篇将介绍如何创建自定义组件,如何向组件传递数据,以及如何在不同页面间复用这些组件。
36 5
「Mac畅玩鸿蒙与硬件23」鸿蒙UI组件篇13 - 自定义组件的创建与使用
|
17天前
|
XML 搜索推荐 前端开发
安卓开发中的自定义视图:打造个性化UI组件
在安卓应用开发中,自定义视图是一种强大的工具,它允许开发者创造独一无二的用户界面元素,从而提升应用的外观和用户体验。本文将通过一个简单的自定义视图示例,引导你了解如何在安卓项目中实现自定义组件,并探讨其背后的技术原理。我们将从基础的View类讲起,逐步深入到绘图、事件处理以及性能优化等方面。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和技巧。
下一篇
DataWorks