Browse Source

Tooltip: refactor code no longer generates additinal html tag, resolve #2423

qingwei.li 8 years ago
parent
commit
5150731e1e

+ 2 - 10
packages/theme-default/src/table.css

@@ -38,16 +38,8 @@
       z-index: 1;
     }
 
-    .el-tooltip {
-      display: block;
-    }
-
-    .el-tooltip__rel {
-      display: block;
-
-      .cell {
-         white-space: nowrap;
-      }
+    .el-tooltip.cell {
+      white-space: nowrap;
     }
 
     @e empty-block {

+ 0 - 7
packages/theme-default/src/tooltip.css

@@ -3,13 +3,6 @@
 
 @component-namespace el {
   @b tooltip {
-    display: inline-block;
-
-    @e rel {
-      display: inline-block;
-      position: relative;
-    }
-
     @e popper {
       position: absolute;
       border-radius: 4px;

+ 103 - 0
packages/tooltip/src/main.js

@@ -0,0 +1,103 @@
+import Popper from 'element-ui/src/utils/vue-popper';
+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'
+    },
+    options: {
+      default() {
+        return {
+          boundariesPadding: 10,
+          gpuAcceleration: false
+        };
+      }
+    }
+  },
+
+  beforeCreate() {
+    this.popperVM = new Vue({
+      data: { node: '' },
+      render(h) {
+        return this.node;
+      }
+    }).$mount();
+  },
+
+  render(h) {
+    this.popperVM.node = (
+      <transition
+        name={ this.transition }
+        onAfterLeave={ this.doDestroy }>
+        <div
+          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) return this.$slots.default;
+
+    const vnode = this.$slots.default[0];
+    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.handleClosePopper);
+    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) {
+      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.manual) return;
+      clearTimeout(this.timeout);
+      this.showPopper = false;
+    }
+  }
+};

+ 0 - 75
packages/tooltip/src/main.vue

@@ -1,75 +0,0 @@
-<template>
-  <div
-    class="el-tooltip"
-    @mouseenter="handleShowPopper"
-    @mouseleave="handleClosePopper">
-    <div class="el-tooltip__rel" ref="reference">
-      <slot></slot>
-    </div>
-
-    <transition :name="transition" @after-leave="doDestroy">
-      <div
-        class="el-tooltip__popper"
-        :class="['is-' + effect, popperClass]"
-        ref="popper"
-        v-show="!disabled && showPopper">
-        <slot name="content"><div v-text="content"></div></slot>
-      </div>
-    </transition>
-  </div>
-</template>
-
-<script>
-import Popper from 'element-ui/src/utils/vue-popper';
-
-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'
-    },
-    options: {
-      default() {
-        return {
-          boundariesPadding: 10,
-          gpuAcceleration: false
-        };
-      }
-    }
-  },
-
-  methods: {
-    handleShowPopper() {
-      if (this.manual) return;
-      this.timeout = setTimeout(() => {
-        this.showPopper = true;
-      }, this.openDelay);
-    },
-
-    handleClosePopper() {
-      if (this.manual) return;
-      clearTimeout(this.timeout);
-      this.showPopper = false;
-    }
-  }
-};
-</script>

+ 18 - 10
test/unit/specs/tooltip.spec.js

@@ -6,22 +6,27 @@ describe('Tooltip', () => {
     destroyVM(vm);
   });
 
-  it('create', () => {
+  it('create', done => {
     vm = createVue(`
-      <el-tooltip content="提示文字">
+      <el-tooltip ref="tooltip" content="提示文字">
         <button>click</button>
       </el-tooltip>`);
 
-    expect(vm.$el.querySelector('.el-tooltip__popper')).to.have.property('textContent', '提示文字');
+    vm.$nextTick(_ => {
+      expect(vm.$refs.tooltip.popperVM.$el).to.have.property('textContent', '提示文字');
+      done();
+    });
   });
 
-  it('custom popper class', () => {
+  it('custom popper class', done => {
     vm = createVue(`
-      <el-tooltip content="提示文字" popper-class="custom-popper">
+      <el-tooltip ref="tooltip" content="提示文字" popper-class="custom-popper">
         <button>click</button>
       </el-tooltip>`);
-
-    expect(vm.$el.querySelector('.el-tooltip__popper').classList.contains('custom-popper')).to.true;
+    vm.$nextTick(_ => {
+      expect(vm.$refs.tooltip.popperVM.$el.classList.contains('custom-popper')).to.true;
+      done();
+    });
   });
 
   describe('manual', () => {
@@ -79,12 +84,15 @@ describe('Tooltip', () => {
     });
   });
 
-  it('light mode', () => {
+  it('light mode', done => {
     vm = createVue(`
-      <el-tooltip content="abc" effect="light">
+      <el-tooltip ref="tooltip" content="abc" effect="light">
         <button>abc</button>
       </el-tooltip>
     `);
-    expect(vm.$el.querySelector('.is-light')).to.exist;
+    vm.$nextTick(_ => {
+      expect(vm.$refs.tooltip.popperVM.$el.classList.contains('is-light')).to.exist;
+      done();
+    });
   });
 });