Commit fcf3cace8e7eee39ff90edc13ee1663b7f8c24c5
1 parent
1b737fdc
Poptip & Tooltip add transfer prop
Using transfer prop, the dom will be transfered to body.
Showing
7 changed files
with
68 additions
and
65 deletions
Show diff stats
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; |