Commit fcf3cace8e7eee39ff90edc13ee1663b7f8c24c5

Authored by 梁灏
1 parent 1b737fdc

Poptip & Tooltip add transfer prop

Using transfer prop, the dom will be transfered to body.
examples/components/test.vue
1 <template> 1 <template>
2 - <Select v-model="model1" style="width:200px">  
3 - <Option v-for="item in cityList" :value="item.value" :key="item.value">{{ item.label }}</Option>  
4 - </Select> 2 + <Poptip trigger="hover" title="提示标题" :transfer="true" placement="left" content="提示内容">
  3 + <Button>hover 激活</Button>
  4 + </Poptip>
5 </template> 5 </template>
6 <script> 6 <script>
7 export default { 7 export default {
8 - data () {  
9 - return {  
10 - cityList: [  
11 - {  
12 - value: 'beijing',  
13 - label: '北京市'  
14 - },  
15 - {  
16 - value: 'shanghai',  
17 - label: '上海市'  
18 - },  
19 - {  
20 - value: 'shenzhen',  
21 - label: '深圳市'  
22 - },  
23 - {  
24 - value: 'hangzhou',  
25 - label: '杭州市'  
26 - },  
27 - {  
28 - value: 'nanjing',  
29 - label: '南京市'  
30 - },  
31 - {  
32 - value: 'chongqing',  
33 - label: '重庆市'  
34 - }  
35 - ],  
36 - model1: ''  
37 - }  
38 - } 8 +
39 } 9 }
40 -</script>  
41 \ No newline at end of file 10 \ No newline at end of file
  11 +</script>
examples/routers/poptip.vue
1 <template> 1 <template>
2 <div> 2 <div>
3 - <Poptip trigger="hover" title="提示标题" content="提示内容"> 3 + <Poptip trigger="hover" transfer title="提示标题" content="提示内容">
4 <Button>hover 激活</Button> 4 <Button>hover 激活</Button>
5 </Poptip> 5 </Poptip>
6 <Poptip title="提示标题" content="提示内容"> 6 <Poptip title="提示标题" content="提示内容">
examples/routers/table.vue
@@ -8,6 +8,7 @@ @@ -8,6 +8,7 @@
8 :data="data3"></Table> 8 :data="data3"></Table>
9 </template> 9 </template>
10 <script> 10 <script>
  11 + import test from '../components/test.vue';
11 export default { 12 export default {
12 data () { 13 data () {
13 return { 14 return {
@@ -59,20 +60,7 @@ @@ -59,20 +60,7 @@
59 fixed: 'right', 60 fixed: 'right',
60 width: 120, 61 width: 120,
61 render: (h, params) => { 62 render: (h, params) => {
62 - return h('div', [  
63 - h('Button', {  
64 - props: {  
65 - type: 'text',  
66 - size: 'small'  
67 - }  
68 - }, '查看'),  
69 - h('Button', {  
70 - props: {  
71 - type: 'text',  
72 - size: 'small'  
73 - }  
74 - }, '编辑')  
75 - ]); 63 + return h(test);
76 } 64 }
77 } 65 }
78 ], 66 ],
examples/routers/tooltip.vue
1 <template> 1 <template>
2 - <Tooltip placement="top" content="Tooltip 文字提示" :delay="1000">  
3 - <Button @click="disabled = true">延时1秒显示</Button>  
4 - </Tooltip> 2 + <div>
  3 + <Tooltip placement="top" transfer content="Tooltip 文字提示" :delay="1000">
  4 + <Button @click="disabled = true">延时1秒显示</Button>
  5 + </Tooltip>
  6 + <Tooltip placement="top" transfer content="Tooltip 文字提示">
  7 + <Button @click="disabled = true">延时1秒显示</Button>
  8 + </Tooltip>
  9 + </div>
5 </template> 10 </template>
6 <script> 11 <script>
7 export default { 12 export default {
src/components/poptip/poptip.vue
@@ -13,7 +13,14 @@ @@ -13,7 +13,14 @@
13 <slot></slot> 13 <slot></slot>
14 </div> 14 </div>
15 <transition name="fade"> 15 <transition name="fade">
16 - <div :class="[prefixCls + '-popper']" :style="styles" ref="popper" v-show="visible"> 16 + <div
  17 + :class="[prefixCls + '-popper']"
  18 + :style="styles"
  19 + ref="popper"
  20 + v-show="visible"
  21 + @mouseenter="handleMouseenter"
  22 + @mouseleave="handleMouseleave"
  23 + v-transfer-dom:forbidden="transfer">
17 <div :class="[prefixCls + '-content']"> 24 <div :class="[prefixCls + '-content']">
18 <div :class="[prefixCls + '-arrow']"></div> 25 <div :class="[prefixCls + '-arrow']"></div>
19 <div :class="[prefixCls + '-inner']" v-if="confirm"> 26 <div :class="[prefixCls + '-inner']" v-if="confirm">
@@ -41,6 +48,7 @@ @@ -41,6 +48,7 @@
41 import Popper from '../base/popper'; 48 import Popper from '../base/popper';
42 import iButton from '../button/button.vue'; 49 import iButton from '../button/button.vue';
43 import clickoutside from '../../directives/clickoutside'; 50 import clickoutside from '../../directives/clickoutside';
  51 + import TransferDom from '../../directives/transfer-dom';
44 import { oneOf } from '../../utils/assist'; 52 import { oneOf } from '../../utils/assist';
45 import Locale from '../../mixins/locale'; 53 import Locale from '../../mixins/locale';
46 54
@@ -49,7 +57,7 @@ @@ -49,7 +57,7 @@
49 export default { 57 export default {
50 name: 'Poptip', 58 name: 'Poptip',
51 mixins: [ Popper, Locale ], 59 mixins: [ Popper, Locale ],
52 - directives: { clickoutside }, 60 + directives: { clickoutside, TransferDom },
53 components: { iButton }, 61 components: { iButton },
54 props: { 62 props: {
55 trigger: { 63 trigger: {
@@ -83,6 +91,10 @@ @@ -83,6 +91,10 @@
83 }, 91 },
84 cancelText: { 92 cancelText: {
85 type: String 93 type: String
  94 + },
  95 + transfer: {
  96 + type: Boolean,
  97 + default: false
86 } 98 }
87 }, 99 },
88 data () { 100 data () {
@@ -161,13 +173,21 @@ @@ -161,13 +173,21 @@
161 if (this.trigger !== 'hover' || this.confirm) { 173 if (this.trigger !== 'hover' || this.confirm) {
162 return false; 174 return false;
163 } 175 }
164 - this.visible = true; 176 + if (this.enterTimer) clearTimeout(this.enterTimer);
  177 + this.enterTimer = setTimeout(() => {
  178 + this.visible = true;
  179 + }, 100);
165 }, 180 },
166 handleMouseleave () { 181 handleMouseleave () {
167 if (this.trigger !== 'hover' || this.confirm) { 182 if (this.trigger !== 'hover' || this.confirm) {
168 return false; 183 return false;
169 } 184 }
170 - this.visible = false; 185 + if (this.enterTimer) {
  186 + clearTimeout(this.enterTimer);
  187 + this.enterTimer = setTimeout(() => {
  188 + this.visible = false;
  189 + }, 100);
  190 + }
171 }, 191 },
172 cancel () { 192 cancel () {
173 this.visible = false; 193 this.visible = false;
src/components/tooltip/tooltip.vue
@@ -4,7 +4,13 @@ @@ -4,7 +4,13 @@
4 <slot></slot> 4 <slot></slot>
5 </div> 5 </div>
6 <transition name="fade"> 6 <transition name="fade">
7 - <div :class="[prefixCls + '-popper']" ref="popper" v-show="!disabled && (visible || always)"> 7 + <div
  8 + :class="[prefixCls + '-popper']"
  9 + ref="popper"
  10 + v-show="!disabled && (visible || always)"
  11 + @mouseenter="handleShowPopper"
  12 + @mouseleave="handleClosePopper"
  13 + v-transfer-dom:forbidden="transfer">
8 <div :class="[prefixCls + '-content']"> 14 <div :class="[prefixCls + '-content']">
9 <div :class="[prefixCls + '-arrow']"></div> 15 <div :class="[prefixCls + '-arrow']"></div>
10 <div :class="[prefixCls + '-inner']"><slot name="content">{{ content }}</slot></div> 16 <div :class="[prefixCls + '-inner']"><slot name="content">{{ content }}</slot></div>
@@ -15,12 +21,14 @@ @@ -15,12 +21,14 @@
15 </template> 21 </template>
16 <script> 22 <script>
17 import Popper from '../base/popper'; 23 import Popper from '../base/popper';
  24 + import TransferDom from '../../directives/transfer-dom';
18 import { oneOf } from '../../utils/assist'; 25 import { oneOf } from '../../utils/assist';
19 26
20 const prefixCls = 'ivu-tooltip'; 27 const prefixCls = 'ivu-tooltip';
21 28
22 export default { 29 export default {
23 name: 'Tooltip', 30 name: 'Tooltip',
  31 + directives: { TransferDom },
24 mixins: [Popper], 32 mixins: [Popper],
25 props: { 33 props: {
26 placement: { 34 placement: {
@@ -35,7 +43,7 @@ @@ -35,7 +43,7 @@
35 }, 43 },
36 delay: { 44 delay: {
37 type: Number, 45 type: Number,
38 - default: 0 46 + default: 100
39 }, 47 },
40 disabled: { 48 disabled: {
41 type: Boolean, 49 type: Boolean,
@@ -48,6 +56,10 @@ @@ -48,6 +56,10 @@
48 always: { 56 always: {
49 type: Boolean, 57 type: Boolean,
50 default: false 58 default: false
  59 + },
  60 + transfer: {
  61 + type: Boolean,
  62 + default: false
51 } 63 }
52 }, 64 },
53 data () { 65 data () {
@@ -57,14 +69,19 @@ @@ -57,14 +69,19 @@
57 }, 69 },
58 methods: { 70 methods: {
59 handleShowPopper() { 71 handleShowPopper() {
  72 + if (this.timeout) clearTimeout(this.timeout);
60 this.timeout = setTimeout(() => { 73 this.timeout = setTimeout(() => {
61 this.visible = true; 74 this.visible = true;
62 }, this.delay); 75 }, this.delay);
63 }, 76 },
64 handleClosePopper() { 77 handleClosePopper() {
65 - clearTimeout(this.timeout);  
66 - if (!this.controlled) {  
67 - this.visible = false; 78 + if (this.timeout) {
  79 + clearTimeout(this.timeout);
  80 + if (!this.controlled) {
  81 + this.timeout = setTimeout(() => {
  82 + this.visible = false;
  83 + }, 100);
  84 + }
68 } 85 }
69 } 86 }
70 } 87 }
src/directives/transfer-dom.js
@@ -15,7 +15,8 @@ function getTarget (node) { @@ -15,7 +15,8 @@ function getTarget (node) {
15 } 15 }
16 16
17 const directive = { 17 const directive = {
18 - inserted (el, { value }, vnode) { 18 + inserted (el, { value, arg }, vnode) {
  19 + if (arg.forbidden) return false;
19 el.className = el.className ? el.className + ' v-transfer-dom' : 'v-transfer-dom'; 20 el.className = el.className ? el.className + ' v-transfer-dom' : 'v-transfer-dom';
20 const parentNode = el.parentNode; 21 const parentNode = el.parentNode;
21 if (!parentNode) return; 22 if (!parentNode) return;
@@ -36,7 +37,8 @@ const directive = { @@ -36,7 +37,8 @@ const directive = {
36 } 37 }
37 } 38 }
38 }, 39 },
39 - componentUpdated (el, { value }) { 40 + componentUpdated (el, { value, arg }) {
  41 + if (arg.forbidden) return false;
40 // need to make sure children are done updating (vs. `update`) 42 // need to make sure children are done updating (vs. `update`)
41 const ref$1 = el.__transferDomData; 43 const ref$1 = el.__transferDomData;
42 if (!ref$1) return; 44 if (!ref$1) return;
@@ -60,7 +62,8 @@ const directive = { @@ -60,7 +62,8 @@ const directive = {
60 getTarget(value).appendChild(el); 62 getTarget(value).appendChild(el);
61 } 63 }
62 }, 64 },
63 - unbind: function unbind (el, binding) { 65 + unbind (el, { arg } ) {
  66 + if (arg.forbidden) return false;
64 el.className = el.className.replace('v-transfer-dom', ''); 67 el.className = el.className.replace('v-transfer-dom', '');
65 const ref$1 = el.__transferDomData; 68 const ref$1 = el.__transferDomData;
66 if (!ref$1) return; 69 if (!ref$1) return;