element/packages/tooltip/src/main.js

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;
}
}
};