fix: [tooltip] mount every time

This commit is contained in:
wanlei 2017-11-03 18:06:00 +08:00
parent 67b357893a
commit 09382b3e50
4 changed files with 124 additions and 82 deletions

View File

@ -0,0 +1,66 @@
<template>
<div>
<tool-tip
placement="bottom"
:title="showText">
<h1 @click="boom" style="display: inline-block">This is just a test, put your cursor here</h1>
</tool-tip>
<ant-button>2223</ant-button>
<div class="box">
<table>
<tr v-for="(tr, index) in table" :key="index">
<td v-for="(td, i) in tr" :key="i">
<tool-tip v-if="td" :placement="td" :title="td"><AntButton type="primary">{{td}}</AntButton></tool-tip>
</td>
</tr>
</table>
</div>
</div>
</template>
<script>
import { ToolTip, Button } from '../../../components'
import '../../../components/button/style'
export default {
name: 'tooltip-basic',
data() {
return {
show: true,
showText: '你好啊233',
table: [
['', 'topLeft', 'top', 'topRight', ''],
['leftTop', '', '', '', 'rightTop'],
['left', '', '', '', 'right'],
['leftBottom', '', '', '', 'rightBottom'],
['', 'bottomLeft', 'bottom', 'bottomRight', ''],
]
}
},
methods: {
boom() {
this.showText += '3'
}
},
components: {
ToolTip,
AntButton: Button,
},
beforeUpdate() {
console.info(90909090)
}
}
</script>
<style scoped lang="less">
.box {
margin: 100px;
}
table {
td {
padding: 20px;
}
p {
text-align: center;
vertical-align: middle;
}
}
</style>

View File

@ -1,3 +1,4 @@
import ToolTip from './tooltip.vue'
import './style'
export default ToolTip

View File

@ -33,7 +33,6 @@ export default {
visible: false,
left: 0,
top: 0,
domNode: null,
}
},
computed: {
@ -44,42 +43,46 @@ export default {
}
},
},
created() {
const div = document.createElement('div')
document.body.appendChild(div)
const that = this
const vnode = new Vue({
data() {
return {
left: 0,
top: 0,
}
},
render(h) {
return (
<transition name="zoom-big">
<div
v-show={that.visible}
class={`ant-tooltip ant-tooltip-placement-${that.placement}`}
style={{ left: this.left + 'px', top: this.top + 'px' }}
>
<div class="ant-tooltip-content">
<div class="ant-tooltip-arrow"/>
<div class="ant-tooltip-inner">
<span>{that.title}</span>
methods: {
mountNode(callback) {
if (this.vnode) {
callback()
return
}
const div = document.createElement('div')
document.body.appendChild(div)
const that = this
const vnode = new Vue({
data() {
return {
left: 0,
top: 0,
}
},
render(h) {
return (
<transition name="zoom-big">
<div
v-show={that.visible}
class={`ant-tooltip ant-tooltip-placement-${that.placement}`}
style={{ left: this.left + 'px', top: this.top + 'px' }}
>
<div class="ant-tooltip-content">
<div class="ant-tooltip-arrow"/>
<div class="ant-tooltip-inner">
<span>{that.title}</span>
</div>
</div>
</div>
</div>
</transition>
)
}
}).$mount(div)
this.$nextTick(() => {
this.vnode = vnode
this.domNode = div
})
},
methods: {
</transition>
)
}
}).$mount(div)
this.$nextTick(() => {
this.vnode = vnode
callback()
})
},
onPopupAlign: (placement, domNode, target, align) => {
if (!placement) {
return;
@ -118,10 +121,10 @@ export default {
left += window.scrollX
const ret = { left, top }
if (/top/.test(placement)) ret.top -= popup.height
if (/bottom/.test(placement)) ret.top += height
if (/left/.test(placement)) ret.left -= popup.width
if (/right/.test(placement)) ret.left += width
if (/top/.test(placement)) ret.top -= popup.height + 5
if (/bottom/.test(placement)) ret.top += height + 5
if (/left/.test(placement)) ret.left -= popup.width + 10
if (/right/.test(placement)) ret.left += width + 5
if (/Left/.test(placement)) {
} else if(/Right/.test(placement)) {
@ -138,41 +141,43 @@ export default {
return ret
},
showNode() {
this.visible = true
this.$nextTick(() => {
const popup = this.vnode.$el.getBoundingClientRect()
const content = this.$el.getBoundingClientRect()
const { left, top } = this.computeOffset(popup, content, this.placement)
this.vnode.left = left
this.vnode.top = top
this.mountNode(() => {
this.visible = true
this.$nextTick(() => {
const popup = this.vnode.$el.getBoundingClientRect()
const content = this.$el.getBoundingClientRect()
const { left, top } = this.computeOffset(popup, content, this.placement)
this.vnode.left = left
this.vnode.top = top
})
this.onPopupAlign(this.placement, this.$el, this.vnode.$el, { offset: [0,0] })
})
this.onPopupAlign(this.placement, this.$el, this.vnode.$el, { offset: [0,0] })
},
hideNode() {
this.visible = false
}
},
render(h) {
let node = this.vnode
const inner = this.$slots.default[0]
inner.data = inner.data || {}
inner.data.on = inner.data.on || {}
inner.data.on.mouseenter = this.addEventHandle(inner.data.on.mouseenter, this.showNode)
inner.data.on.mouseleave = this.addEventHandle(inner.data.on.mouseleave, this.hideNode)
// console.info(inner)
return this.$slots.default[0]
},
updated() {
if (!this.vnode) return
const popup = this.vnode.$el.getBoundingClientRect()
const content = this.$el.getBoundingClientRect()
const { left, top } = this.computeOffset(popup, content, this.placement)
this.vnode.left = left
this.vnode.top = top
},
beforeDestory() {
console.info('没有成功清除实例 看vue panel')
beforeDestroy() {
if (!this.vnode) return
this.vnode.$el.remove()
this.vnode.$destroy();
this.domNode && this.domNode.remove()
}
}
</script>

View File

@ -1,30 +0,0 @@
<template>
<div>
<tool-tip
placement="top"
:title="showText">
<h1 @click="boom" style="display: inline-block">This is just a test, put your cursor here</h1>
</tool-tip>
</div>
</template>
<script>
import { ToolTip } from '../components'
export default {
name: '',
data() {
return {
show: true,
showText: '你好啊23'
}
},
methods: {
boom() {
this.showText += '3'
}
},
components: {
ToolTip
}
}
</script>