基于ElementUI實(shí)現(xiàn)v-tooltip指令的示例代碼
文本溢出隱藏并使用tooltip 提示的需求,相信在平時(shí)的開發(fā)中會(huì)經(jīng)常遇到。
常規(guī)做法一般是使用 elementui 的 el-tooltip 組件,在每次組件更新的時(shí)候去獲取元素的寬度/高度判斷是否被隱藏。
受益于 element-plus的虛擬觸發(fā) tooltip 的實(shí)現(xiàn),決定探究在 vue2 上也以一種簡單的方式實(shí)現(xiàn) tooltip 提示。
探究 tooltip 源碼
源碼地址:https://github.com/ElemeFE/element/blob/dev/packages/tooltip/src/main.js
在 render 階段,可以看出 tooltip 組件會(huì)提取插槽中的第一個(gè)子元素進(jìn)行渲染
render(h) {
// ....
const firstElement = this.getFirstElement();
if (!firstElement) return null;
const data = firstElement.data = firstElement.data || {};
data.staticClass = this.addTooltipClass(data.staticClass);
return firstElement;
},
所以在 mounted 階段, $el 會(huì)獲取到的其實(shí)就是傳入插槽的第一個(gè)元素。
并且在這個(gè)階段,會(huì)給元素添加上mouseenter、mouseleave的事件監(jiān)聽,來控制 hover 狀態(tài)下是否顯示 tooltip
mounted() {
this.referenceElm = this.$el;
if (this.$el.nodeType === 1) {
this.$el.setAttribute('aria-describedby', this.tooltipId);
this.$el.setAttribute('tabindex', this.tabindex);
on(this.referenceElm, 'mouseenter', this.show);
on(this.referenceElm, 'mouseleave', this.hide);
// ...
}
函數(shù)式調(diào)用 tooltip
在了解了 el-tooltip 的運(yùn)行原理之后,我們能夠封裝一個(gè)模板,并且支持函數(shù)式調(diào)用。
通過 getEl 獲取一個(gè) DOM 元素,以便在喚起 tooltip 時(shí)元素的所處位置。
<template>
<el-tooltip ref="triggerRef" :manual="true">
<template #content>
{{ internalContent }}
</template>
</el-tooltip>
</template>
<script>
// useOverflowHidden 的邏輯自行定義
import { useOverflowHidden } from './use-overflow-hidden'
export default {
name: 'TooltipFunction',
props: {
getEl: {
type: Function,
default: () => null
},
getContent: {
type: Function,
default: () => ''
}
},
data() {
return {
internalContent: '',
isHover: false,
}
},
mounted() {
const el = this.getEl()
if (!el) return
this.$refs.triggerRef.referenceElm = el;
el.addEventListener('mousemove', this.onMouseEnter, false)
el.addEventListener('mouseleave', this.onMouseLeave, false)
},
methods: {
onMouseEnter() {
if (!this.isHover && useOverflowHidden(this.getEl())) {
this.internalContent = this.getContent()
this.isHover = true
this.$refs.triggerRef.showPopper = true
}
},
onMouseLeave() {
if (this.isHover) {
this.isHover = false;
this.$refs.triggerRef.showPopper = false
}
},
onDestroy() {
const el = this.getEl()
if (!el) return
el.removeEventListener('mousemove', this.onMouseEnter)
el.removeEventListener('mouseleave', this.onMouseLeave)
}
},
}
</script>
模版完成過后,我們還需要再寫一個(gè)函數(shù)用來調(diào)用 TooltipFunction。
import Vue from 'vue'
import TooltipFunction from './tooltipFunction.vue'
function useTooltip(el) {
const Ctor = Vue.extend(TooltipWrapper)
const instance = new Ctor({
propsData: {
getContent,
getEl: () => el,
},
})
instance.$mount()
return instance
}
在代碼中,我們只需在 mounted 中對需要 tooltip 的元素進(jìn)行一次注冊即可。
<template>
<div ref="dataRef">foo</div>
</template>
<script>
import useTooltip from './use-tooltip.js'
export default {
mounted() {
const el = this.$refs.dataRef
if (el) {
// 獲取 content 的函數(shù)邏輯自行定義
this.tooltipIns = useTooltip(el, () => 'foo')
}
},
beforeDestory() {
this.tooltipIns?.onDestroy()
this.tooltipIns?.$destroy()
}
}
</script>
自定義指令 v-tooltip
上述雖然實(shí)現(xiàn)了函數(shù)式調(diào)用 tooltip 的方式,但是還需要對每個(gè)元素進(jìn)行 ref 聲明獲取 DOM,以及組件銷毀時(shí) tooltip 的生命周期管理。vue 的自定義指令恰好能輕松解決這兩件事情。
function setupTooltipDirection() {
const tooltipSymbol = Symbol('tooltip')
Vue.directive('tooltip', {
bind(el: HTMLElement) {
// 這里我們使用 DOM 元素上的 tooltip-content 作為 通信
const instance = createTooltipFactory(el, () => el.getAttribute('tooltip-content') || '')
Reflect.set(el, tooltipSymbol, instance)
},
unbind(el) {
const ins = Reflect.get(el, tooltipSymbol)
if (!ins) return
ins.onDestroy()
ins.$destroy()
Reflect.set(el, tooltipSymbol, null)
},
})
}
在業(yè)務(wù)中,即可通過簡單的指令實(shí)現(xiàn) tooltip 的提示需求:
<template>
<div v-tooltip tooltip-content="hello">hello</div>
</template>
到此這篇關(guān)于基于ElementUI實(shí)現(xiàn)v-tooltip指令的示例代碼的文章就介紹到這了,更多相關(guān)ElementUI實(shí)現(xiàn)v-tooltip內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
vue router 跳轉(zhuǎn)時(shí)打開新頁面的示例方法
這篇文章主要介紹了vue router 跳轉(zhuǎn)時(shí)打開新頁面的示例方法,本文通過示例代碼給大家介紹的非常詳細(xì),具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2019-07-07
優(yōu)雅的將ElementUI表格變身成樹形表格的方法步驟
這篇文章主要介紹了優(yōu)雅的將ElementUI表格變身成樹形表格的方法步驟,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2019-04-04
Vue預(yù)覽圖片和視頻的幾種實(shí)現(xiàn)方式
本文主要介紹了Vue預(yù)覽圖片和視頻的幾種實(shí)現(xiàn)方式,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2023-07-07

