可自定义设置以下属性:
提示框内容最大宽度(maxWidth),类型:number,默认 120px
展示的文本(content),类型:string,默认暂无内容,支持string | slot
提示的文本(title),类型:string,默认暂无提示,支持string | slot
效果如下图:
①创建提示框组件Tooltip.vue:
<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">
<slot name="title">{
{ title }}</slot>
</div>
<div class="m-arrow">
<span class="u-arrow"></span>
</div>
</div>
<div ref="contentRef" class="u-content">
<slot>{
{ content }}</slot>
</div>
</div>
</template>
<script>
export default {
name: 'Tooltip',
props: {
maxWidth: { // 提示框内容最大宽度
type: Number,
default: 120
},
content: { // 展示的文本
type: String,
default: '暂无内容' // string | slot
},
title: { // 提示的文本
type: String,
default: '暂无提示' // string | slot
}
},
data () {
return {
hideTimer: null,
top: 0, // 提示框top定位
left: 0, // 提示框left定位
visible: false
}
},
mounted () {
this.getPosition()
},
methods: {
getPosition () {
const rect = this.$refs.contentRef.getBoundingClientRect()
const targetTop = rect.top
const targetLeft = rect.left
const targetWidth = rect.width
const titleWidth = this.$refs.titleRef.offsetWidth // 提示文本宽度
const titleHeight = this.$refs.titleRef.offsetHeight // 提示文本高度
this.top = targetTop - titleHeight
this.left = targetLeft - (titleWidth - targetWidth) / 2
},
onShow () {
this.getPosition()
clearTimeout(this.hideTimer)
this.visible = true
},
onHide () {
this.hideTimer = setTimeout(() => {
this.visible = false
}, 100)
}
}
}
</script>
<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);
transition: transform .25s, opacity .25s;
.u-title {
padding: 10px;
margin: 0 auto;
word-break: break-all;
word-wrap: break-word;
background: #FFFFFF;
box-shadow: 0px 0px 7px 1px fade(@themeColor, 36%);
border-radius: 5px;
font-weight: 400;
font-size: 14px;
line-height: 20px;
color: #333;
}
.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;
background: #FFF;
border-radius: 0 0 3px 0;
z-index: 8;
box-shadow: 1px 1px 3px 1px fade(@themeColor, 10%);
}
}
}
.show-tip {
pointer-events: auto;
opacity: 1;
transform: scale(1);
}
.u-content {
cursor: pointer;
font-size: 14px;
line-height: 1.5;
color: #000000;
}
</style>
②在要使用的页面引入:
<template>
<div>
<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">
<!-- <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>
<script>
import Tooltip from './Tooltip'
export default {
name: 'InfoTip',
components: {
Tooltip
},
data () {
return {
content: '',
title: ''
}
},
mounted () {
setTimeout(() => { // 模拟接口调用
this.title = '《哥斯拉大战金刚》是由美国传奇影业公司出品,亚当·温佳德执导,亚历山大·斯卡斯加德、米莉·博比·布朗、丽贝卡·豪尔、凯莉·霍特尔、布莱恩·泰里·亨利、小栗旬联合主演的动作科幻片,于2021于3月26日在中国内地上映'
this.content = '哥斯拉'
}, 1000)
}
}
</script>
<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;
}
.mt150 {
margin-top: 150px;
}
.yellow {
color: #FF9000;
background: #FFF9F0;
}
.blue {
color: #0079DD;
background: #F0F7FD;
}
</style>