mirror of https://github.com/ElemeFE/element
120 lines
2.8 KiB
JavaScript
120 lines
2.8 KiB
JavaScript
import Popper from 'element-ui/src/utils/vue-popper';
|
|
import debounce from 'throttle-debounce/debounce';
|
|
import { getFirstComponentChild } from 'element-ui/src/utils/vdom';
|
|
import Vue from 'vue';
|
|
|
|
export default {
|
|
name: 'ElTooltip',
|
|
|
|
mixins: [Popper],
|
|
|
|
props: {
|
|
openDelay: {
|
|
type: Number,
|
|
default: 0
|
|
},
|
|
disabled: Boolean,
|
|
manual: Boolean,
|
|
effect: {
|
|
type: String,
|
|
default: 'dark'
|
|
},
|
|
popperClass: String,
|
|
content: String,
|
|
visibleArrow: {
|
|
default: true
|
|
},
|
|
transition: {
|
|
type: String,
|
|
default: 'fade-in-linear'
|
|
},
|
|
popperOptions: {
|
|
default() {
|
|
return {
|
|
boundariesPadding: 10,
|
|
gpuAcceleration: false
|
|
};
|
|
}
|
|
}
|
|
},
|
|
|
|
beforeCreate() {
|
|
if (this.$isServer) return;
|
|
|
|
this.popperVM = new Vue({
|
|
data: { node: '' },
|
|
render(h) {
|
|
return this.node;
|
|
}
|
|
}).$mount();
|
|
|
|
this.debounceClose = debounce(200, () => this.handleClosePopper());
|
|
},
|
|
|
|
render(h) {
|
|
if (this.popperVM) {
|
|
this.popperVM.node = (
|
|
<transition
|
|
name={ this.transition }
|
|
onAfterLeave={ this.doDestroy }>
|
|
<div
|
|
onMouseleave={ () => { this.debounceClose(); this.togglePreventClose(); } }
|
|
onMouseenter= { this.togglePreventClose }
|
|
ref="popper"
|
|
v-show={!this.disabled && this.showPopper}
|
|
class={
|
|
['el-tooltip__popper', 'is-' + this.effect, this.popperClass]
|
|
}>
|
|
{ this.$slots.content || this.content }
|
|
</div>
|
|
</transition>);
|
|
}
|
|
|
|
if (!this.$slots.default || !this.$slots.default.length) return this.$slots.default;
|
|
|
|
const vnode = getFirstComponentChild(this.$slots.default);
|
|
if (!vnode) return vnode;
|
|
const data = vnode.data = vnode.data || {};
|
|
const on = vnode.data.on = vnode.data.on || {};
|
|
|
|
on.mouseenter = this.addEventHandle(on.mouseenter, this.handleShowPopper);
|
|
on.mouseleave = this.addEventHandle(on.mouseleave, this.debounceClose);
|
|
data.staticClass = this.concatClass(data.staticClass, 'el-tooltip');
|
|
|
|
return vnode;
|
|
},
|
|
|
|
mounted() {
|
|
this.referenceElm = this.$el;
|
|
},
|
|
|
|
methods: {
|
|
addEventHandle(old, fn) {
|
|
return old ? Array.isArray(old) ? old.concat(fn) : [old, fn] : fn;
|
|
},
|
|
|
|
concatClass(a, b) {
|
|
if (a && a.indexOf(b) > -1) return a;
|
|
return a ? b ? (a + ' ' + b) : a : (b || '');
|
|
},
|
|
|
|
handleShowPopper() {
|
|
if (this.manual) return;
|
|
clearTimeout(this.timeout);
|
|
this.timeout = setTimeout(() => {
|
|
this.showPopper = true;
|
|
}, this.openDelay);
|
|
},
|
|
|
|
handleClosePopper() {
|
|
if (this.preventClose || this.manual) return;
|
|
clearTimeout(this.timeout);
|
|
this.showPopper = false;
|
|
},
|
|
|
|
togglePreventClose() {
|
|
this.preventClose = !this.preventClose;
|
|
}
|
|
}
|
|
};
|