Vue3文字提示(Tooltip)

68 篇文章 4 订阅
66 篇文章 3 订阅

Vue2文字提示(Tooltip)

可自定义设置以下属性:

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

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

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

  • 提示文本字体大小(fontSize),类型:number,单位px,默认 14,优先级高于 overlayStyle

  • 提示文本字体颜色(color),类型:string,默认 '#FFF',优先级高于 overlayStyle

  • 提示框背景色(backgroundColor),类型:string,默认 'rgba(0, 0, 0, .85)',优先级高于 overlayStyle

  • 提示框内容区域样式(overlayStyle),类型:CSSProperties,默认 {}

效果如下图: 在线预览

 

注:组件引用方法 import { rafTimeout, cancelRaf } from '../index' 请参考以下博客: 

使用requestAnimationFrame模拟实现setTimeout和setInterval_theMuseCatcher的博客-CSDN博客使用requestAnimationFrame模拟实现setTimeout和setInterval!https://blog.csdn.net/Dandrose/article/details/130167061

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

<script setup lang="ts">
import { ref } from 'vue'
import type { CSSProperties } from 'vue'
import { rafTimeout, cancelRaf } from '../index'
interface Props {
  maxWidth?: number // 提示框内容最大宽度,单位px
  content?: string // 展示的文本 string | slot
  tooltip?: string // 提示的文本 string | slot
  fontSize?: number // 提示文本字体大小,单位px,优先级高于 overlayStyle
  color?: string // 提示文本字体颜色,优先级高于 overlayStyle
  backgroundColor?: string // 提示框背景颜色,优先级高于 overlayStyle
  overlayStyle?: CSSProperties // 提示框内容区域样式
}
withDefaults(defineProps<Props>(), {
  maxWidth: 120,
  content: '暂无内容',
  tooltip: '暂无提示',
  fontSize: 14,
  color: '#FFF',
  backgroundColor: 'rgba(0, 0, 0, .85)',
  overlayStyle: () => ({})
})
const visible = ref(false)
const hideTimer = ref()
const top = ref(0) // 提示框top定位
const left = ref(0) // 提示框left定位
const contentRef = ref() // 声明一个同名的模板引用
const tooltipRef = ref() // 声明一个同名的模板引用
const emit = defineEmits(['openChange'])
function getPosition() {
  const contentWidth = contentRef.value.offsetWidth // 展示文本宽度
  const tooltipWidth = tooltipRef.value.offsetWidth // 提示文本宽度
  const tooltipHeight = tooltipRef.value.offsetHeight // 提示文本高度
  top.value = tooltipHeight + 4
  left.value = (tooltipWidth - contentWidth) / 2
}
function onShow() {
  getPosition()
  cancelRaf(hideTimer.value)
  visible.value = true
  emit('openChange', visible.value)
}
function onHide(): void {
  hideTimer.value = rafTimeout(() => {
    visible.value = false
    emit('openChange', visible.value)
  }, 100)
}
</script>
<template>
  <div class="m-tooltip" @mouseenter="onShow" @mouseleave="onHide">
    <div
      ref="tooltipRef"
      class="m-tooltip-content"
      :class="{ 'show-tip': visible }"
      :style="`--tooltip-font-size: ${fontSize}px; --tooltip-color: ${color}; --tooltip-background-color: ${backgroundColor}; max-width: ${maxWidth}px; transform-origin: 50% ${top}px; top: ${-top}px; left: ${-left}px;`"
      @mouseenter="onShow"
      @mouseleave="onHide"
    >
      <div class="u-tooltip" :style="overlayStyle">
        <slot name="tooltip">{{ tooltip }}</slot>
      </div>
      <div class="m-tooltip-arrow">
        <span class="u-tooltip-arrow"></span>
      </div>
    </div>
    <div ref="contentRef">
      <slot>{{ content }}</slot>
    </div>
  </div>
</template>
<style lang="less" scoped>
.m-tooltip {
  position: relative;
  display: inline-block;
  .m-tooltip-content {
    position: absolute;
    z-index: 999;
    width: max-content;
    padding-bottom: 12px;
    pointer-events: none;
    transform: scale(0.8);
    opacity: 0;
    transition:
      transform 0.1s cubic-bezier(0.78, 0.14, 0.15, 0.86),
      opacity 0.1s cubic-bezier(0.78, 0.14, 0.15, 0.86);
    .u-tooltip {
      min-width: 32px;
      min-height: 32px;
      padding: 6px 8px;
      font-size: var(--tooltip-font-size);
      color: var(--tooltip-color);
      line-height: 1.5714285714285714;
      text-align: justify;
      text-decoration: none;
      word-break: break-all;
      background-color: var(--tooltip-background-color);
      border-radius: 6px;
      box-shadow:
        0 6px 16px 0 rgba(0, 0, 0, 0.08),
        0 3px 6px -4px rgba(0, 0, 0, 0.12),
        0 9px 28px 8px rgba(0, 0, 0, 0.05);
    }
    .m-tooltip-arrow {
      position: absolute;
      z-index: 9;
      left: 50%;
      bottom: 12px;
      transform: translateX(-50%) translateY(100%) rotate(180deg);
      display: block;
      pointer-events: none;
      width: 16px;
      height: 16px;
      overflow: hidden;
      &::before {
        position: absolute;
        bottom: 0;
        inset-inline-start: 0;
        width: 16px;
        height: 8px;
        background-color: var(--tooltip-background-color);
        clip-path: path(
          'M 0 8 A 4 4 0 0 0 2.82842712474619 6.82842712474619 L 6.585786437626905 3.0710678118654755 A 2 2 0 0 1 9.414213562373096 3.0710678118654755 L 13.17157287525381 6.82842712474619 A 4 4 0 0 0 16 8 Z'
        );
        content: '';
      }
      &::after {
        position: absolute;
        width: 8.970562748477143px;
        height: 8.970562748477143px;
        bottom: 0;
        inset-inline: 0;
        margin: auto;
        border-radius: 0 0 2px 0;
        transform: translateY(50%) rotate(-135deg);
        box-shadow: 3px 3px 7px rgba(0, 0, 0, 0.1);
        z-index: 0;
        background: transparent;
        content: '';
      }
    }
  }
  .show-tip {
    pointer-events: auto;
    transform: scale(1);
    opacity: 1;
  }
}
</style>

 ②在要使用的页面引入:

<script setup lang="ts">
import Tooltip from './Tooltip.vue'
function openChange (visible: boolean) {
  console.log('visible:', visible)
}
</script>
<template>
  <div class="ml60">
    <h1>{{ $route.name }} {{ $route.meta.title }}</h1>
    <h2 class="mt30 mb10">基本使用</h2>
    <Space :gap="30">
      <Tooltip :maxWidth="240" @open-change="openChange">
        <template #tooltip>特斯拉(Tesla)是美国一家电动汽车及能源公司,总部位于帕洛阿托(Palo Alto),市值达2100亿美元,产销电动汽车、太阳能板、及储能设备</template>
        <Button type="primary">特斯拉</Button>
      </Tooltip>
      <Tooltip :maxWidth="380" @open-change="openChange">
        <template #tooltip>《哥斯拉》由传奇影业、华纳兄弟影业公司等联合出品。该片讲述了世界各地异常自然灾害的发生频率的上升,被隐瞒了几十年的秘密逐渐浮出水面,人类即将面临一场来自远古的浩劫,三只强大怪兽也将轮番登场掀起层层高潮,这场混战也将在怪兽与人类之间打响的故事</template>
        <Button type="primary">哥斯拉</Button>
      </Tooltip>
    </Space>
    <h2 class="mt30 mb10">自定义样式</h2>
    <Tooltip
      :maxWidth="320"
      :fontSize="18"
      color="rgba(0, 0, 0, 0.85)"
      backgroundColor="#FFF"
      :overlayStyle="{padding: '12px 18px', borderRadius: '12px'}">
      <template #tooltip>《哥斯拉大战金刚》是由美国传奇影业公司出品。该片讲述了人类计划将所有巨兽从地球上抹去,而传说中哥斯拉和金刚两个王者被设计进行了对决,最终两大巨兽联手破坏人类计划的故事。</template>
      <Button type="primary">哥斯拉大战金刚</Button>
    </Tooltip>
    <h2 class="mt30 mb10">暂无数据</h2>
    <Tooltip>
      <Button type="primary">暂无数据</Button>
    </Tooltip>
  </div>
</template>
  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论
好的,针对您的问题,我可以给出以下步骤: 1. 创建组件 在您的项目中,创建一个 `Tooltip.vue` 组件,用于显示文字提示。代码如下: ``` <template> <div class="tooltip" v-if="visible"> {{ message }} </div> </template> <script lang="ts"> import { defineComponent, ref, watch } from 'vue'; export default defineComponent({ name: 'Tooltip', props: { content: { type: String, required: true, }, delay: { type: Number, default: 500, }, }, setup(props) { const visible = ref(false); const message = ref(props.content); let timer: any = null; watch( () => props.content, (value) => { message.value = value; visible.value = false; clearTimeout(timer); } ); const showTooltip = () => { timer = setTimeout(() => { visible.value = true; }, props.delay); }; const hideTooltip = () => { visible.value = false; clearTimeout(timer); }; return { visible, message, showTooltip, hideTooltip, }; }, }); </script> <style scoped> .tooltip { position: absolute; z-index: 9999; background-color: #333; color: #fff; padding: 5px 10px; border-radius: 5px; font-size: 14px; line-height: 1.5; } </style> ``` 上述代码中,我们定义了一个 `Tooltip` 组件,它有两个 props:`content` 和 `delay`,分别表示提示内容和延迟显示时间。在 `setup` 函数中,我们使用 `ref` 定义了 `visible` 和 `message` 变量,分别表示提示框是否可见和提示内容。我们使用 `watch` 监听 `props.content` 的变化,当内容发生改变时,更新 `message` 变量,并隐藏提示框。当用户鼠标移入被绑定的元素时,我们使用 `setTimeout` 设置延迟,然后显示提示框;当用户鼠标移出元素时,隐藏提示框。 2. 在页面中使用组件 在需要显示提示的元素中,使用 `v-tooltip` 指令绑定提示内容,如下所示: ``` <template> <div> <button v-tooltip="'这是一个按钮'">按钮</button> <span v-tooltip="'这是一个文字'">文字</span> </div> </template> <script lang="ts"> import { defineComponent } from 'vue'; import Tooltip from './Tooltip.vue'; export default defineComponent({ name: 'App', components: { Tooltip, }, }); </script> ``` 使用 `v-tooltip` 指令时,将提示内容作为指令的参数传入即可。在组件中,我们使用 `props.content` 获取到这个内容,并将其显示在提示框中。 以上就是使用 Vue3 编写文字提示组件的简单步骤,希望能对您有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值