Tooltip指令
这个指令是在工作中经常用到的, 组内的大佬基于element 组件的 el-tooltip 实现的, 由于这个博客没有增加UI库(增加后博客仓库也有点笨重), 所以我暂时添加一个手写的简单指令, 后续再研究下popper 这个库, 基于这个库看能不能再写一个.
1. 手写简易版
能实现基本的功能, 但是还有功能简单, 渲染优化问题
javascript
let tooltipEle = null
export const tooltip = {
// 在绑定元素的父组件
// 及他自己的所有子节点都挂载完成后调用
mounted(el, binding) {
const initEle = () => {
if (tooltipEle) tooltipEle = null
el.parentNode.style.position = 'relative'
const { left, top, width } = el.getBoundingClientRect()
tooltipEle = document.createElement('span')
tooltipEle.innerHTML = binding.value
tooltipEle.style.position = 'absolute'
tooltipEle.style.width = width + 'px'
tooltipEle.style.height = el.scrollHeight + 'px'
tooltipEle.style.bottom = 30 + 'px'
tooltipEle.style.left = 10 + 'px'
tooltipEle.style.boxShadow = '0px 4px 8px 0px rgba(41,48,64,0.4)'
tooltipEle.style.borderRadius = '4px'
tooltipEle.style.backgroundColor = '#fff'
tooltipEle.style.padding = '4px 8px'
el.parentNode.appendChild(tooltipEle)
}
el.addEventListener('mouseenter', () => {
if (
el.scrollWidth > el.offsetWidth ||
binding.modifiers.show ||
el.scrollHeight > el.offsetHeight
) {
el.style.cursor = 'pointer'
initEle()
}
})
el.addEventListener('mouseleave', () => {
tooltipEle && tooltipEle.remove()
})
},
// 在绑定元素的父组件
// 及他自己的所有子节点都更新后调用
updated(el, binding) {
tooltipEle.innerHTML = binding.value
},
}2. vue2的版本
这个版本主要是参考组内大佬写的, 自己加了一些注释, 代码源文件在这里
javascript
import Vue from '../source/vue.js'
const state = Vue.observable({ visible: true, content: '' })
let tooltip = null
Vue.directive('tool', {
// 指令初始化
bind(el, binding) {
// 初始化tooltip组件
if (!tooltip) {
// 使用extend创建vue组件, 平时用的更多的是vue.component
const Instance = Vue.extend({
render(h) {
h('el-tooltip', {
ref: 'tooltip',
props: {
effect: 'light',
placement: 'top',
value: state.visible,
content: state.content
}
})
}
})
tooltip = new Instance().$mount()
document.body.appendChild(tooltip)
}
el.addEventListener('mouseenter', function(e) {
if (el.scrollWidth > el.offsetWidth || el.scrollHeight > el.offsetHeight) {
const tip = tooltip.$refs.tooltip;
// 每次建新的tooltip的时候销毁前一个, 防止速度过快出现闪烁
tip.$refs.popper && (tip.$refs.popper.style.display = 'none');
tip.doDestroy();
tip.setExpectedState(true);
// tooltip每次渲染的时候都需要有一个基本元素, 这里是为其赋值
tip.referenceElm = e.srcElement;
// 更新全局状态state
state.visible = true;
state.content = binding.value;
}
})
el.addEventListener('mouseleave', function(e) {
tooltip.$refs.tooltip.referenceElm = e.srcElement;
state.visible = false;
})
}
})