Vue3文字提示(Tooltip)

Vue2文字提示(Tooltip)

可自定义设置以下属性:

  • 提示框内容最大宽度(maxWidth),类型:number,默认 120px

  • 展示的文本(content),类型:string,默认暂无内容,支持string | slot

  • 提示的文本(title),类型:string,默认暂无提示,支持string | slot

  • 提示文本字体大小(fontSize),类型:number,默认 14px

  • 提示文本字体颜色(color),类型:string,默认 'rgba(0,0,0,.85)'

  • 提示框背景色(backgroundColor),类型:string,默认 '#FFF'

效果如下图: 

  

 

 ①创建提示框组件Tooltip.vue:

<script setup lang="ts">
import { ref, onMounted } from 'vue'
import { rafTimeout, cancelRaf } from '../index'
defineProps({ // 运行时声明
  maxWidth: { // 提示框内容最大宽度
    type: Number,
    default: 120
  },
  content: { // 展示的文本
    type: String,
    default: '暂无内容' // string | slot
  },
  title: { // 提示的文本
    type: String,
    default: '暂无提示' // string | slot
  },
  fontSize: { // 提示文本字体大小
    type: Number,
    default: 14
  },
  color: { // 提示文本字体颜色
    type: String,
    default: 'rgba(0,0,0,.85)'
  },
  backgroundColor: { // 提示框背景色
    type: String,
    default: '#FFF'
  }
})
const visible = ref(false)
const hideTimer = ref()
const top = ref(0) // 提示框top定位
const left = ref(0) // 提示框left定位
const contentRef = ref() // 声明一个同名的模板引用
const titleRef = ref() // 声明一个同名的模板引用

onMounted(() => {
  getPosition()
})
function getPosition () {
  const rect = contentRef.value.getBoundingClientRect()
  const targetTop = rect.top
  const targetLeft = rect.left
  const targetWidth = rect.width
  const titleWidth = titleRef.value.offsetWidth // 提示文本宽度
  const titleHeight = titleRef.value.offsetHeight // 提示文本高度
  top.value = targetTop - titleHeight
  left.value = targetLeft - (titleWidth - targetWidth) / 2
}
function onShow () {
  getPosition()
  cancelRaf(hideTimer.value)
  visible.value = true
}
function onHide (): void {
  hideTimer.value = rafTimeout(() => {
    visible.value = false
  }, 100)
}
</script>
<template>
  <div class="m-tooltip" @mouseenter="onShow" @mouseleave="onHide">
    <div
      ref="titleRef"
      class="m-title"
      :class="{'show-tip': visible}"
      @mouseenter="onShow"
      @mouseleave="onHide"
      :style="`max-width: ${maxWidth}px; top: ${top}px; left: ${left}px;`">
      <div class="u-title" :style="`font-size: ${fontSize}px; color: ${color}; background-color: ${backgroundColor};`">
        <slot name="title">{
   
   { title }}</slot>
      </div>
      <div class="m-arrow">
        <span class="u-arrow" :style="`background-color: ${backgroundColor};`"></span>
      </div>
    </div>
    <div ref="contentRef" class="u-content">
      <slot>{
   
   { content }}</slot>
    </div>
  </div>
</template>
<style lang="less" scoped>
.m-tooltip {
  display: inline-block;
}
.m-title {
  position: fixed;
  z-index: 999;
  padding-bottom: 12px;
  pointer-events: none;
  opacity: 0;
  transform-origin: 50% 75%;
  transform: scale(0.8); // 缩放变换
  -ms-transform: scale(0.8); /* IE 9 */
  -webkit-transform: scale(0.8); /* Safari and Chrome */
  transition: transform .25s, opacity .25s;
  .u-title {
    padding: 10px;
    margin: 0 auto;
    word-break: break-all;
    word-wrap: break-word;
    box-shadow: 0px 0px 5px 1px fade(@themeColor, 36%);
    border-radius: 5px;
    font-weight: 400;
    line-height: 1.5;
    // line-height: 20px;
  }
  .m-arrow {
    position: absolute;
    z-index: 9;
    bottom: 12px;
    left: 50%;
    transform: translate(-50%, 100%);
    width: 15.55px;
    height: 10px;
    border-radius: 0 0 5px 5px;
    overflow: hidden;
    .u-arrow {
      position: absolute;
      left: 50%;
      top: 0px;
      transform: translate(-50%, -50%) rotate(45deg);
      margin: 0 auto;
      width: 11px;
      height: 11px;
      border-radius: 0 0 3px 0;
      z-index: 8;
      box-shadow: 1px 1px 1px 1px fade(@themeColor, 12%);
    }
  }
}
.show-tip {
  pointer-events: auto;
  opacity: 1;
  transform: scale(1); // 缩放变换
  -ms-transform: scale(1); /* IE 9 */
  -webkit-transform: scale(1); /* Safari and Chrome */
}
.u-content {
  cursor: pointer;
  font-size: 14px;
  line-height: 1.5;
  color: #000000;
}
</style>

 ②在要使用的页面引入:

<script setup lang="ts">
import { Tooltip } from './Tooltip.vue'
import { ref, onMounted } from 'vue'
import { rafTimeout } from '../../packages'

const title = ref('')
const content = ref('')

onMounted(() => {
  rafTimeout(() => { // 模拟接口调用
    title.value = '《哥斯拉大战金刚》是由美国传奇影业公司出品,亚当·温佳德执导,亚历山大·斯卡斯加德、米莉·博比·布朗、丽贝卡·豪尔、凯莉·霍特尔、布莱恩·泰里·亨利、小栗旬联合主演的动作科幻片,于2021于3月26日在中国内地上映'
    content.value = '哥斯拉'
  }, 1000)
})
</script>
<template>
  <div>
    <h2 class="mb10">Tooltip 文字提示基本使用</h2>
    <p class="u-info mt150 mb10">普通用法:</p>
    <Tooltip :maxWidth="240">
      <template #title>特斯拉(Tesla)是美国一家电动汽车及能源公司,总部位于帕洛阿托(Palo Alto),市值达2100亿美元,产销电动汽车、太阳能板、及储能设备</template>
      <div class="u-tag yellow">特斯拉</div>
    </Tooltip>
    <p class="u-info ml120 mb10">模拟接口调用:</p>
    <Tooltip :maxWidth="240" :fontSize="14" color="#FFF" backgroundColor="rgba(0,0,0,.85)">
      <!-- <template #title>《哥斯拉大战金刚》是由美国传奇影业公司出品,亚当·温佳德执导,亚历山大·斯卡斯加德、米莉·博比·布朗、丽贝卡·豪尔、凯莉·霍特尔、布莱恩·泰里·亨利、小栗旬联合主演的动作科幻片,于2021于3月26日在中国内地上映</template> -->
      <template #title>{
   
   { title || '--' }}</template>
      <!-- <div class="u-tag blue">哥斯拉</div> -->
      <div class="u-tag blue">{
   
   { content || '--' }}</div>
    </Tooltip>
  </div>
</template>
<style lang="less" scoped>
.u-tag {
  display: inline-block;
  padding: 6px 12px;
  border-radius: 15px;
  font-size: 14px;
  font-weight: 400;
  line-height: 20px;
  cursor: pointer;
}
.u-info {
  display: inline-block;
  font-size: 16px;
}
.yellow {
  color: #FF9000;
  background: #FFF9F0;
}
.blue {
  color: #0079DD;
  background: #F0F7FD;
}
</style>

猜你喜欢

转载自blog.csdn.net/Dandrose/article/details/129493864