基于ElementUI實現(xiàn)v-tooltip指令的示例代碼
文本溢出隱藏并使用tooltip
提示的需求,相信在平時的開發(fā)中會經常遇到。
常規(guī)做法一般是使用 elementui
的 el-tooltip
組件,在每次組件更新的時候去獲取元素的寬度/高度判斷是否被隱藏。
受益于 element-plus
的虛擬觸發(fā) tooltip
的實現(xiàn),決定探究在 vue2 上也以一種簡單的方式實現(xiàn) tooltip
提示。
探究 tooltip 源碼
源碼地址:https://github.com/ElemeFE/element/blob/dev/packages/tooltip/src/main.js
在 render
階段,可以看出 tooltip 組件會提取插槽中的第一個子元素進行渲染
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
會獲取到的其實就是傳入插槽的第一個元素。
并且在這個階段,會給元素添加上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ù)式調用 tooltip
在了解了 el-tooltip
的運行原理之后,我們能夠封裝一個模板,并且支持函數(shù)式調用。
通過 getEl 獲取一個 DOM 元素,以便在喚起 tooltip 時元素的所處位置。
<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>
模版完成過后,我們還需要再寫一個函數(shù)用來調用 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
的元素進行一次注冊即可。
<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
上述雖然實現(xiàn)了函數(shù)式調用 tooltip 的方式,但是還需要對每個元素進行 ref
聲明獲取 DOM,以及組件銷毀時 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è)務中,即可通過簡單的指令實現(xiàn) tooltip 的提示需求:
<template> <div v-tooltip tooltip-content="hello">hello</div> </template>
到此這篇關于基于ElementUI實現(xiàn)v-tooltip指令的示例代碼的文章就介紹到這了,更多相關ElementUI實現(xiàn)v-tooltip內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!
相關文章
優(yōu)雅的將ElementUI表格變身成樹形表格的方法步驟
這篇文章主要介紹了優(yōu)雅的將ElementUI表格變身成樹形表格的方法步驟,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2019-04-04