2020-10-19 13:50:22 +08:00
|
|
|
import {
|
|
|
|
nextTick,
|
|
|
|
reactive,
|
|
|
|
onBeforeMount,
|
|
|
|
onBeforeUnmount,
|
|
|
|
onMounted,
|
|
|
|
getCurrentInstance,
|
|
|
|
watch,
|
|
|
|
} from 'vue'
|
|
|
|
import PopupManager from '../popup-manager'
|
|
|
|
import getScrollBarWidth from '../scrollbar-width'
|
|
|
|
import { getStyle, addClass, removeClass, hasClass } from '../dom'
|
|
|
|
import isServer from '../isServer'
|
|
|
|
|
|
|
|
let idSeed = 1
|
|
|
|
|
|
|
|
let scrollBarWidth
|
|
|
|
|
|
|
|
export const usePopup1 = {
|
|
|
|
watch: {
|
|
|
|
visible(val) {
|
|
|
|
if (val) {
|
|
|
|
if (this._opening) return
|
|
|
|
if (!this.rendered) {
|
|
|
|
this.rendered = true
|
|
|
|
nextTick(() => {
|
|
|
|
this.open()
|
|
|
|
}).then(() => {
|
|
|
|
//
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
this.open()
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
this.close()
|
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
const usePopup = (props, doClose) => {
|
|
|
|
let _popupId
|
|
|
|
let _opening = false
|
|
|
|
let _closing = false
|
|
|
|
let vm
|
|
|
|
let _closeTimer = null
|
|
|
|
let _openTimer = null
|
2020-10-30 23:26:57 +08:00
|
|
|
const state = reactive({
|
2020-10-19 13:50:22 +08:00
|
|
|
opened: false,
|
|
|
|
bodyPaddingRight: null,
|
|
|
|
computedBodyPaddingRight: 0,
|
|
|
|
withoutHiddenClass: true,
|
|
|
|
rendered: false,
|
|
|
|
visible: false,
|
|
|
|
})
|
|
|
|
|
|
|
|
onMounted(() => {
|
|
|
|
vm = getCurrentInstance()
|
|
|
|
})
|
|
|
|
|
|
|
|
onBeforeMount(() => {
|
|
|
|
_popupId = 'popup-' + idSeed++
|
|
|
|
PopupManager.register(_popupId, vm)
|
|
|
|
})
|
|
|
|
|
|
|
|
onBeforeUnmount(() => {
|
|
|
|
PopupManager.deregister(_popupId)
|
|
|
|
PopupManager.closeModal(_popupId)
|
|
|
|
restoreBodyStyle()
|
|
|
|
})
|
|
|
|
|
|
|
|
const doOpen = merProps => {
|
|
|
|
if (isServer) return
|
|
|
|
if (state.opened) return
|
|
|
|
|
|
|
|
_opening = true
|
|
|
|
|
|
|
|
const dom = vm.vnode.el
|
|
|
|
|
|
|
|
const modal = merProps.modal
|
|
|
|
|
|
|
|
const zIndex = merProps.zIndex
|
|
|
|
if (zIndex) {
|
|
|
|
PopupManager.zIndex = zIndex
|
|
|
|
}
|
|
|
|
|
|
|
|
if (modal) {
|
|
|
|
if (_closing) {
|
|
|
|
PopupManager.closeModal(_popupId)
|
|
|
|
_closing = false
|
|
|
|
}
|
|
|
|
PopupManager.openModal(_popupId, PopupManager.nextZIndex(), props.modalAppendToBody ? undefined : dom, merProps.modalClass, merProps.modalFade)
|
|
|
|
if (merProps.lockScroll) {
|
|
|
|
state.withoutHiddenClass = !hasClass(document.body, 'el-popup-parent--hidden')
|
|
|
|
if (state.withoutHiddenClass) {
|
|
|
|
state.bodyPaddingRight = document.body.style.paddingRight
|
|
|
|
state.computedBodyPaddingRight = parseInt(getStyle(document.body, 'paddingRight'), 10)
|
|
|
|
}
|
|
|
|
scrollBarWidth = getScrollBarWidth()
|
|
|
|
const bodyHasOverflow = document.documentElement.clientHeight < document.body.scrollHeight
|
|
|
|
const bodyOverflowY = getStyle(document.body, 'overflowY')
|
|
|
|
if (scrollBarWidth > 0 && (bodyHasOverflow || bodyOverflowY === 'scroll') && state.withoutHiddenClass) {
|
|
|
|
document.body.style.paddingRight = state.computedBodyPaddingRight + scrollBarWidth + 'px'
|
|
|
|
}
|
|
|
|
addClass(document.body, 'el-popup-parent--hidden')
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (getComputedStyle(dom).position === 'static') {
|
|
|
|
dom.style.position = 'absolute'
|
|
|
|
}
|
|
|
|
|
|
|
|
dom.style.zIndex = PopupManager.nextZIndex()
|
|
|
|
state.opened = true
|
|
|
|
|
|
|
|
doAfterOpen()
|
|
|
|
}
|
|
|
|
|
|
|
|
const open = function (options?) {
|
|
|
|
if (!state.rendered) {
|
|
|
|
state.rendered = true
|
|
|
|
}
|
|
|
|
const _props = Object.assign({}, props || vm.proxy, options)
|
|
|
|
|
|
|
|
if (_closeTimer) {
|
|
|
|
clearTimeout(_closeTimer)
|
|
|
|
_closeTimer = null
|
|
|
|
}
|
|
|
|
clearTimeout(_openTimer)
|
|
|
|
|
|
|
|
const openDelay = Number(_props.openDelay)
|
|
|
|
if (openDelay > 0) {
|
|
|
|
_openTimer = setTimeout(() => {
|
|
|
|
_openTimer = null
|
|
|
|
doOpen(_props)
|
|
|
|
}, openDelay)
|
|
|
|
} else {
|
|
|
|
doOpen(_props)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const close = () => {
|
|
|
|
if (_openTimer !== null) {
|
|
|
|
clearTimeout(_openTimer)
|
|
|
|
_openTimer = null
|
|
|
|
}
|
|
|
|
clearTimeout(_closeTimer)
|
|
|
|
|
|
|
|
const closeDelay = Number(props.closeDelay)
|
|
|
|
|
|
|
|
if (closeDelay > 0) {
|
|
|
|
_closeTimer = setTimeout(() => {
|
|
|
|
_closeTimer = null
|
|
|
|
doClose()
|
|
|
|
}, closeDelay)
|
|
|
|
} else {
|
|
|
|
doClose()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
const doAfterOpen = () => {
|
|
|
|
_opening = false
|
|
|
|
}
|
|
|
|
|
|
|
|
const restoreBodyStyle = () => {
|
|
|
|
if (props.modal && state.withoutHiddenClass) {
|
|
|
|
document.body.style.paddingRight = state.bodyPaddingRight
|
|
|
|
removeClass(document.body, 'el-popup-parent--hidden')
|
|
|
|
}
|
|
|
|
state.withoutHiddenClass = true
|
|
|
|
}
|
|
|
|
|
|
|
|
const doAfterClose = () => {
|
|
|
|
PopupManager.closeModal(_popupId)
|
|
|
|
_closing = false
|
|
|
|
}
|
|
|
|
|
|
|
|
const updateClosingFlag = value => {
|
|
|
|
_closing = value
|
|
|
|
}
|
|
|
|
|
|
|
|
watch(() => state.visible, async val => {
|
|
|
|
if (val) {
|
|
|
|
if (_opening) return
|
|
|
|
if (!state.rendered) {
|
|
|
|
state.rendered = true
|
|
|
|
await nextTick()
|
|
|
|
open()
|
|
|
|
} else {
|
|
|
|
open()
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
close()
|
|
|
|
}
|
|
|
|
})
|
|
|
|
|
|
|
|
return {
|
|
|
|
state,
|
|
|
|
close,
|
|
|
|
doAfterClose,
|
|
|
|
updateClosingFlag,
|
|
|
|
restoreBodyStyle,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
export default usePopup
|