UNPKG

element-ui

Version:

A Component Library for Vue.js.

127 lines (109 loc) 3.46 kB
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: 'el-fade-in-linear' }, popperOptions: { default() { return { boundariesPadding: 10, gpuAcceleration: false }; } }, enterable: { type: Boolean, default: true } }, 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.setExpectedState(false); this.debounceClose(); } } onMouseenter= { () => { this.setExpectedState(true); } } 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 || {}; const nativeOn = vnode.data.nativeOn = vnode.data.nativeOn || {}; on.mouseenter = this.addEventHandle(on.mouseenter, () => { this.setExpectedState(true); this.handleShowPopper(); }); on.mouseleave = this.addEventHandle(on.mouseleave, () => { this.setExpectedState(false); this.debounceClose(); }); nativeOn.mouseenter = this.addEventHandle(nativeOn.mouseenter, () => { this.setExpectedState(true); this.handleShowPopper(); }); nativeOn.mouseleave = this.addEventHandle(nativeOn.mouseleave, () => { this.setExpectedState(false); 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.expectedState || this.manual) return; clearTimeout(this.timeout); this.timeout = setTimeout(() => { this.showPopper = true; }, this.openDelay); }, handleClosePopper() { if (this.enterable && this.expectedState || this.manual) return; clearTimeout(this.timeout); this.showPopper = false; }, setExpectedState(expectedState) { this.expectedState = expectedState; } } };