fix: drawer children update issue #209

pull/225/head
tangjinzhou 2018-10-10 13:43:10 +08:00
parent 328cdc853d
commit 4ebcc99055
5 changed files with 147 additions and 122 deletions

View File

@ -41,7 +41,7 @@ export default {
}, },
renderComponent (props = {}, ready) { renderComponent (props = {}, ready) {
const { visible, getComponent, forceRender, getContainer, parent } = this const { visible, forceRender, getContainer, parent } = this
const self = this const self = this
if (visible || parent.$refs._component || forceRender) { if (visible || parent.$refs._component || forceRender) {
let el = this.componentEl let el = this.componentEl
@ -74,7 +74,7 @@ export default {
}) })
}, },
render () { render () {
return getComponent(this.comProps) return self.getComponent(this.comProps)
}, },
}) })
} else { } else {

View File

@ -113,7 +113,7 @@ const Drawer = {
let header let header
if (title) { if (title) {
header = ( header = (
<div class={`${prefixCls}-header`}> <div key='header' class={`${prefixCls}-header`}>
<div class={`${prefixCls}-title`}>{title}</div> <div class={`${prefixCls}-title`}>{title}</div>
</div> </div>
) )
@ -122,6 +122,7 @@ const Drawer = {
if (closable) { if (closable) {
closer = ( closer = (
<button <button
key='closer'
onClick={this.close} onClick={this.close}
aria-label='Close' aria-label='Close'
class={`${prefixCls}-close`} class={`${prefixCls}-close`}
@ -139,7 +140,7 @@ const Drawer = {
> >
{header} {header}
{closer} {closer}
<div class={`${prefixCls}-body`} style={bodyStyle}> <div key='body' class={`${prefixCls}-body`} style={bodyStyle}>
{this.$slots.default} {this.$slots.default}
</div> </div>
</div> </div>

View File

@ -37,7 +37,7 @@ const CollectionCreateForm = Form.create()(
<a-form-item label='Description'> <a-form-item label='Description'>
{getFieldDecorator('description')(<a-input type='textarea' />)} {getFieldDecorator('description')(<a-input type='textarea' />)}
</a-form-item> </a-form-item>
<a-form-item className='collection-create-form_last-form-item'> <a-form-item class='collection-create-form_last-form-item'>
{getFieldDecorator('modifier', { {getFieldDecorator('modifier', {
initialValue: 'public', initialValue: 'public',
})( })(

View File

@ -20,7 +20,11 @@ import {
function noop () {} function noop () {}
const currentDrawer = {} const currentDrawer = {}
const windowIsUndefined = typeof window === 'undefined' const windowIsUndefined = !(
typeof window !== 'undefined' &&
window.document &&
window.document.createElement
)
Vue.use(antRefDirective) Vue.use(antRefDirective)
const Drawer = { const Drawer = {
mixins: [BaseMixin], mixins: [BaseMixin],
@ -114,6 +118,7 @@ const Drawer = {
this.$nextTick(() => { this.$nextTick(() => {
// dom 没渲染时,重走一遍。 // dom 没渲染时,重走一遍。
if (!this.sFirstEnter && this.container) { if (!this.sFirstEnter && this.container) {
console.log(1)
this.$forceUpdate() this.$forceUpdate()
this.sFirstEnter = true this.sFirstEnter = true
} }
@ -224,7 +229,7 @@ const Drawer = {
} }
}, },
setLevelDomTransform (open, openTransition, placementName, value) { setLevelDomTransform (open, openTransition, placementName, value) {
const { placement, levelMove, duration, ease } = this.$props const { placement, levelMove, duration, ease, getContainer } = this.$props
if (!windowIsUndefined) { if (!windowIsUndefined) {
this.levelDom.forEach(dom => { this.levelDom.forEach(dom => {
if (this.isOpenChange || openTransition) { if (this.isOpenChange || openTransition) {
@ -243,104 +248,108 @@ const Drawer = {
} }
}) })
// 处理 body 滚动 // 处理 body 滚动
const eventArray = ['touchstart'] if (getContainer === 'body') {
const domArray = [document.body, this.maskDom, this.handlerdom, this.contentDom] const eventArray = ['touchstart']
const right = getScrollBarSize(1) const domArray = [document.body, this.maskDom, this.handlerdom, this.contentDom]
let widthTransition = `width ${duration} ${ease}` const right = document.body.scrollHeight > (window.innerHeight || document.documentElement.clientHeight) &&
const trannsformTransition = `transform ${duration} ${ease}` window.innerWidth > document.body.offsetWidth
if (open && document.body.style.overflow !== 'hidden') { ? getScrollBarSize(1) : 0
document.body.style.overflow = 'hidden' let widthTransition = `width ${duration} ${ease}`
if (right) { const trannsformTransition = `transform ${duration} ${ease}`
document.body.style.position = 'relative' if (open && document.body.style.overflow !== 'hidden') {
document.body.style.width = `calc(100% - ${right}px)` document.body.style.overflow = 'hidden'
this.dom.style.transition = 'none' if (right) {
switch (placement) { document.body.style.position = 'relative'
case 'right': document.body.style.width = `calc(100% - ${right}px)`
this.dom.style.transform = `translateX(-${right}px)` this.dom.style.transition = 'none'
this.dom.style.msTransform = `translateX(-${right}px)` switch (placement) {
break case 'right':
case 'top': this.dom.style.transform = `translateX(-${right}px)`
case 'bottom': this.dom.style.msTransform = `translateX(-${right}px)`
this.dom.style.width = `calc(100% - ${right}px)` break
this.dom.style.transform = 'translateZ(0)' case 'top':
break case 'bottom':
default: this.dom.style.width = `calc(100% - ${right}px)`
break this.dom.style.transform = 'translateZ(0)'
break
default:
break
}
clearTimeout(this.timeout)
this.timeout = setTimeout(() => {
this.dom.style.transition = `${trannsformTransition},${widthTransition}`
this.dom.style.width = ''
this.dom.style.transform = ''
this.dom.style.msTransform = ''
})
} }
clearTimeout(this.timeout) // 手机禁滚
this.timeout = setTimeout(() => { domArray.forEach((item, i) => {
this.dom.style.transition = `${trannsformTransition},${widthTransition}` if (!item) {
this.dom.style.width = '' return
this.dom.style.transform = '' }
this.dom.style.msTransform = '' addEventListener(
item,
eventArray[i] || 'touchmove',
i ? this.removeMoveHandler : this.removeStartHandler,
this.passive
)
}) })
} } else if (this.getCrrentDrawerSome()) {
// 手机禁滚 document.body.style.overflow = ''
domArray.forEach((item, i) => { if ((this.isOpenChange || openTransition) && right) {
if (!item) { document.body.style.position = ''
return document.body.style.width = ''
} if (trnasitionStr) {
addEventListener( document.body.style.overflowX = 'hidden'
item, }
eventArray[i] || 'touchmove', this.dom.style.transition = 'none'
i ? this.removeMoveHandler : this.removeStartHandler, let heightTransition
this.passive switch (placement) {
) case 'right': {
}) this.dom.style.transform = `translateX(${right}px)`
} else if (this.getCrrentDrawerSome()) { this.dom.style.msTransform = `translateX(${right}px)`
document.body.style.overflow = '' this.dom.style.width = '100%'
if ((this.isOpenChange || openTransition) && right) { widthTransition = `width 0s ${ease} ${duration}`
document.body.style.position = '' if (this.maskDom) {
document.body.style.width = '' this.maskDom.style.left = `-${right}px`
if (trnasitionStr) { this.maskDom.style.width = `calc(100% + ${right}px)`
document.body.style.overflowX = 'hidden' }
} break
this.dom.style.transition = 'none'
let heightTransition
switch (placement) {
case 'right': {
this.dom.style.transform = `translateX(${right}px)`
this.dom.style.msTransform = `translateX(${right}px)`
this.dom.style.width = '100%'
widthTransition = `width 0s ${ease} ${duration}`
if (this.maskDom) {
this.maskDom.style.left = `-${right}px`
this.maskDom.style.width = `calc(100% + ${right}px)`
} }
break case 'top':
case 'bottom': {
this.dom.style.width = `calc(100% + ${right}px)`
this.dom.style.height = '100%'
this.dom.style.transform = 'translateZ(0)'
heightTransition = `height 0s ${ease} ${duration}`
break
}
default:
break
} }
case 'top': clearTimeout(this.timeout)
case 'bottom': { this.timeout = setTimeout(() => {
this.dom.style.width = `calc(100% + ${right}px)` this.dom.style.transition = `${trannsformTransition},${
this.dom.style.height = '100%' heightTransition ? `${heightTransition},` : ''}${widthTransition}`
this.dom.style.transform = 'translateZ(0)' this.dom.style.transform = ''
heightTransition = `height 0s ${ease} ${duration}` this.dom.style.msTransform = ''
break this.dom.style.width = ''
} this.dom.style.height = ''
default: })
break
} }
clearTimeout(this.timeout) domArray.forEach((item, i) => {
this.timeout = setTimeout(() => { if (!item) {
this.dom.style.transition = `${trannsformTransition},${ return
heightTransition ? `${heightTransition},` : ''}${widthTransition}` }
this.dom.style.transform = '' removeEventListener(
this.dom.style.msTransform = '' item,
this.dom.style.width = '' eventArray[i] || 'touchmove',
this.dom.style.height = '' i ? this.removeMoveHandler : this.removeStartHandler,
this.passive
)
}) })
} }
domArray.forEach((item, i) => {
if (!item) {
return
}
removeEventListener(
item,
eventArray[i] || 'touchmove',
i ? this.removeMoveHandler : this.removeStartHandler,
this.passive
)
})
} }
} }
const { change } = this.$listeners const { change } = this.$listeners
@ -475,28 +484,44 @@ const Drawer = {
return this.open !== undefined ? this.open : this.sOpen return this.open !== undefined ? this.open : this.sOpen
}, },
getTouchParentScroll (root, currentTarget, differX, differY) { getTouchParentScroll (root, currentTarget, differX, differY) {
/**
* 增加 rect
* 当父级 dom overflow 未开启滚动时scrollLeft scrollTop 0, scrollWidth 增加了
* 父级是跟随子级的 rect, 直到父级设定了滚动.
*/
const rect = currentTarget.getBoundingClientRect()
if (!currentTarget) { if (!currentTarget) {
return false return false
} else if ( }
(((currentTarget.scrollTop + currentTarget.offsetHeight + currentTarget.offsetTop >= // root 为 drawer-content 设定了 overflow, 判断为 root 的 parent 时结束滚动;
currentTarget.scrollHeight + rect.top && if (currentTarget === root.parentNode) {
differY < 0) || return true
(currentTarget.scrollTop <= 0 && differY > 0)) && }
Math.max(Math.abs(differX), Math.abs(differY)) === Math.abs(differY)) ||
(((currentTarget.scrollLeft + currentTarget.offsetWidth + currentTarget.offsetLeft >= const isY = Math.max(Math.abs(differX), Math.abs(differY)) === Math.abs(differY)
currentTarget.scrollWidth + rect.left && const isX = Math.max(Math.abs(differX), Math.abs(differY)) === Math.abs(differX)
differX < 0) ||
(currentTarget.scrollLeft <= 0 && differX > 0)) && const scrollY = currentTarget.scrollHeight - currentTarget.clientHeight
Math.max(Math.abs(differX), Math.abs(differY)) === Math.abs(differX)) const scrollX = currentTarget.scrollWidth - currentTarget.clientWidth
/**
* <div style="height: 300px">
* <div style="height: 900px"></div>
* </div>
* 在没设定 overflow: auto scroll currentTarget 里获取不到 scrollTop scrollLeft,
* 预先用 scrollTo 来滚动如果取出的值跟滚动前取出不同 currnetTarget 被设定了 overflow; 否则就是上面这种
*/
const t = currentTarget.scrollTop
const l = currentTarget.scrollLeft
currentTarget.scrollTo(currentTarget.scrollLeft + 1, currentTarget.scrollTop + 1)
const currentT = currentTarget.scrollTop
const currentL = currentTarget.scrollLeft
currentTarget.scrollTo(currentTarget.scrollLeft - 1, currentTarget.scrollTop - 1)
if (
isY && (!scrollY || !(currentT - t) ||
(scrollY && (currentTarget.scrollTop >= scrollY && differY < 0 ||
currentTarget.scrollTop <= 0 && differY > 0))
) ||
isX && (!scrollX || !(currentL - l) ||
(scrollX && (currentTarget.scrollLeft >= scrollX && differX < 0 ||
currentTarget.scrollLeft <= 0 && differX > 0))
)
) { ) {
return root === currentTarget || return this.getTouchParentScroll(root, currentTarget.parentNode, differX, differY)
this.getTouchParentScroll(root, currentTarget.parentNode, differX, differY)
} }
return false return false
}, },
@ -546,7 +571,7 @@ const Drawer = {
const { getContainer, wrapperClassName } = this.$props const { getContainer, wrapperClassName } = this.$props
const open = this.getOpen() const open = this.getOpen()
currentDrawer[this.drawerId] = open ? this.container : open currentDrawer[this.drawerId] = open ? this.container : open
this.children = this.getChildToRender(this.sFirstEnter ? open : false) const children = this.getChildToRender(this.sFirstEnter ? open : false)
if (!getContainer) { if (!getContainer) {
const directives = [{ const directives = [{
name: 'ant-ref', name: 'ant-ref',
@ -559,21 +584,20 @@ const Drawer = {
class={wrapperClassName} class={wrapperClassName}
{...{ directives }} {...{ directives }}
> >
{this.children} {children}
</div> </div>
) )
} }
if (!this.container || !open && !this.sFirstEnter) { if (!this.container || !open && !this.sFirstEnter) {
return null return null
} }
return ( return (
<ContainerRender <ContainerRender
parent={this} parent={this}
visible visible
autoMount autoMount
autoDestroy={false} autoDestroy={false}
getComponent={() => this.children} getComponent={() => children}
getContainer={this.getSelfContainer} getContainer={this.getSelfContainer}
children={({ renderComponent, removeContainer }) => { children={({ renderComponent, removeContainer }) => {
this.renderComponent = renderComponent this.renderComponent = renderComponent

View File

@ -1,4 +1,4 @@
// base in 1.7.3 // base in 1.7.6
// export this package's api // export this package's api
import Drawer from './Drawer' import Drawer from './Drawer'