当前位置: 首页 > 工具软件 > Tooltip > 使用案例 >

vue3.0 组件篇 Tooltip

艾成益
2023-12-01

组件介绍

当用户将鼠标悬停在一个页面元素上时,通常需要显示与该元素相关的信息。这就是Tooltip组件的用途。Tooltip是一种小型弹出框,它显示有关特定页面元素的信息,例如按钮、链接或图标。Tooltip通常以半透明的气泡形式呈现,并出现在页面元素的旁边或下方。

它可以改善用户体验,使用户更容易理解页面元素的功能和意图。用户可以通过将鼠标悬停在页面元素上来快速了解有关该元素的信息,而无需离开当前页面或浏览其他页面。

  1. 定位问题,很重要,top topLeft topRight bottom bottomLeft bottomRight left right,tooltip可以出现在不同的位置
  2. 采用默认插槽的方式,将需要tooltip的内容放置
  3. 通过父组件传入的visible进行手动控制tooltip的显现和隐藏
  4. 可以自定义tooltip背景色,如果自定义了,文字为白色
  5. 监听状态的变化,通过$emit 实现@change的调用
  6. 自定义tooltip的宽度,这个很重要
  7. 默认触发tooltip的方式为hover ,触发的方式还有click,如果从父组件传入了visible,hover和click将会失效

组件安装与使用

需要先安装vue3-dxui

yarn add vue3-dxui

或者

npm install vue3-dxui

全局main.ts中引入css

import { createApp } from 'vue'
import App from './App.vue'
import router from './router'
import store from './store'
import 'vue3-dxui/dxui/dxui.css'

createApp(App).use(store).use(router).mount('#app')

按需引入

<script>
import { Tooltip } from 'vue3-dxui'

export default {
  components: {
  	Tooltip
  }
}
</script>

组件代码

<template>
  <div
    @mouseenter="handleHoverTooltipShow"
    @mouseleave="handleHoverTooltipHide"
    @click="handleClickTooltipChange"
    class="dx-tooltip-warpper"
    :class="`trigger-${trigger} position-${position}`"
  >
    <!-- 在顶层通过传入的visible进行控制 -->
    <div v-show="visible !== undefined ? visible : true" class="dx-tooltip-max-width">
      <!-- 在内层通过组件自身的tooltipvisible进行控制 -->
      <div
        v-show="tooltipVisible"
        class="dx-tooltip-content-warpper"
        :style="
          background ? { background, color: '#fff', borderColor: background, width } : { width }
        "
      >
        <div class="tooltip-title">
          {{ title }}
        </div>
        <div
          class="tooltip-icon"
          :style="background ? { background, color: '#fff', borderColor: background } : {}"
        />
      </div>
    </div>
    <slot />
  </div>
</template>

<script lang="ts">
import { ComponentInternalInstance, getCurrentInstance, ref, PropType, watch } from 'vue'

import { Data } from './types'

export default {
  props: {
    // tooltip的内容
    title: {
      required: false,
      default: '',
      type: String
    },
    // tooltip的触发方式 hover click
    trigger: {
      required: false,
      default: 'hover',
      type: String
    },
    // 可以用来手动控制tooltip的出现或者消失
    visible: {
      required: false,
      default: undefined,
      type: Boolean as PropType<boolean | undefined>
    },
    // tooltip出现的位置
    position: {
      required: false,
      default: 'topLeft',
      type: String
    },
    // 可以设置tooltip的背景颜色
    background: {
      required: false,
      default: '',
      type: String
    },
    // 自定义tooltip的宽度,tooltip的宽度受被包裹元素的影响,这里提供自定义
    width: {
      required: false,
      default: '',
      type: String
    }
  },
  watch: {
    // 对外界传入的visible进行监听,选用了vue2的写法,因为外界传入的visible可能不是一个ref只是一个简单的boolean值
    visible(newval: boolean) {
      // this.$emit 会报错 说$emit在类型里面不存在,所以用这样的方式,但实际上是存在的,将来可能需要改进下,知道的朋友说一下
      const that: any = this
      that?.$emit('change', newval)
    }
  },
  setup(propsData: Data) {
    let tooltipVisible = ref(false)
    if (propsData.visible !== undefined) {
      tooltipVisible = ref(true)
    }

    const currentInstance: ComponentInternalInstance | null = getCurrentInstance()

    const handleHoverTooltipShow = () => {
      if (propsData.trigger === 'hover' && propsData.visible === undefined) {
        tooltipVisible.value = true
      }
    }

    const handleHoverTooltipHide = () => {
      if (propsData.trigger === 'hover' && propsData.visible === undefined) {
        tooltipVisible.value = false
      }
    }

    const handleClickTooltipChange = () => {
      if (propsData.trigger === 'click' && propsData.visible === undefined) {
        tooltipVisible.value = !tooltipVisible.value
      }
    }

    // 如果是组件内部自己维护的tooltipVisible,就用vue3的watch触发监听,实现change的回调
    watch(tooltipVisible, (newval) => {
      currentInstance?.emit('change', newval)
    })

    return {
      tooltipVisible,
      handleHoverTooltipShow,
      handleHoverTooltipHide,
      handleClickTooltipChange
    }
  }
}
</script>

<style lang="scss" scoped>
@import '@/scss/layout.scss';

.dx-tooltip-warpper {
  display: inline-block;
  position: relative;
  cursor: pointer;

  .dx-tooltip-max-width {
    text-align: initial;
    position: absolute;
    z-index: 1000;
    width: 100%;
  }

  .dx-tooltip-content-warpper {
    display: inline-block;
    text-align: initial;
    padding: 6px 10px;
    background: $background-color;
    border: $border;
    border-radius: 4px;
    min-width: 80px;
  }

  .tooltip-title {
    font-size: 14px;
    z-index: 1000;
  }

  .tooltip-icon {
    width: 12px;
    height: 12px;
    position: absolute;
    z-index: 999;
    transform: rotate(45deg);
    background: $background-color;
    border-bottom: $border;
    border-right: $border;
  }
}

.dx-tooltip-warpper.position-topLeft {
  .dx-tooltip-content-warpper {
    position: absolute;
    bottom: calc(100% + 10px);
  }
}

.dx-tooltip-warpper.position-top {
  .dx-tooltip-max-width {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
  }
  .dx-tooltip-content-warpper {
    position: absolute;
    bottom: calc(100% + 10px);
    left: 50%;
    transform: translateX(-50%);
  }

  .tooltip-icon {
    position: absolute;
    left: 50%;
    margin-left: -4px;
  }
}

.dx-tooltip-warpper.position-topRight {
  .dx-tooltip-max-width {
    position: absolute;
    right: 0;
  }

  .dx-tooltip-content-warpper {
    position: absolute;
    right: 0;
    bottom: calc(100% + 10px);
  }

  .tooltip-icon {
    position: absolute;
    right: 12px;
  }
}

.dx-tooltip-warpper.position-bottomLeft {
  .dx-tooltip-max-width {
    position: absolute;
    bottom: -10px;
  }

  .dx-tooltip-content-warpper {
    position: absolute;
  }

  .tooltip-icon {
    position: absolute;
    top: -6px;
    transform: rotate(-135deg);
  }
}

.dx-tooltip-warpper.position-bottom {
  .dx-tooltip-max-width {
    position: absolute;
    bottom: -10px;
    left: 50%;
    transform: translateX(-50%);
  }
  .dx-tooltip-content-warpper {
    position: absolute;
    left: 50%;
    transform: translateX(-50%);
  }

  .tooltip-icon {
    position: absolute;
    top: -6px;
    left: 50%;
    margin-left: -4px;
    transform: rotate(-135deg);
  }
}

.dx-tooltip-warpper.position-bottomRight {
  .dx-tooltip-max-width {
    position: absolute;
    bottom: -10px;
    right: 0;
  }

  .dx-tooltip-content-warpper {
    position: absolute;
    right: 0;
  }

  .tooltip-icon {
    position: absolute;
    top: -6px;
    right: 12px;
    transform: rotate(-135deg);
  }
}

.dx-tooltip-warpper.position-left {
  .dx-tooltip-max-width {
    position: absolute;
    top: 50%;
  }

  .dx-tooltip-content-warpper {
    position: absolute;
    transform: translateX(-100%) translateY(-50%);
    left: -10px;
  }

  .tooltip-icon {
    position: absolute;
    right: -6px;
    top: calc(50% - 6px);
    transform: rotate(-45deg);
  }
}

.dx-tooltip-warpper.position-right {
  .dx-tooltip-max-width {
    position: absolute;
    top: 50%;
    margin-left: calc(100% + 10px);
  }

  .dx-tooltip-content-warpper {
    position: absolute;
    transform: translateY(-50%);
  }

  .tooltip-icon {
    position: absolute;
    left: -6px;
    top: calc(50% - 6px);
    transform: rotate(135deg);
  }
}
</style>

参数说明

名称说明
titlestring类型,tooltip的内容
triggerhover 或者 click , tooltip的触发方式,默认值是hover
visibleboolean类型,可以通过父组件来自定义控制trigger的消失或隐藏
positiontooltip出现的位置,默认值是 topLeft
background背景色,如果有背景色设置,字体默认是白色
widthtooltip的宽度

事件

事件名称说明
@change当tooltip显示或者隐藏状态发生改变时触发,返回值是当前tooltip的visible的值

关于dxui组件库

dxui组件库是我个人搭建的vue3 前端交互组件库,倾向于pc网站的交互模式。

  1. 如果你有任何问题,请在博客下方评论留言,我尽可能24小时内回复。
  2. dxui新上线的官网域名变更 http://dxui.cn
  3. npm 官方链接 https://www.npmjs.com/package/vue3-dxui
  4. 如果你想看完整源码 https://github.com/757363985/dxui
 类似资料: