vc-popup
Version:
vue popup components with power position and animation support and back key support as well
161 lines (133 loc) • 4.24 kB
JavaScript
import Vue from 'vue'
import Router from './router'
import popupBaseTpl from './popup-base.vue'
import popupContainerTpl from './popup-conatiner.vue'
function top (arr) { return arr[arr.length - 1] }
function prev (arr) { return arr[arr.length - 2] }
function splitPopupValue (val) {
return val ? decodeURIComponent(val).split('/') : []
}
var Popup
if (Vue.prototype.__popup__ !== undefined) {
Popup = Vue.prototype.__popup__
} else {
require('../../style/basic-animatin.css')
require('../../style/animation-duration-preset.css')
var popupContainer = null
var vmBaseOfRouterId = {}
var constructorOfRouterId = {}
var PopupBaseConstructor = Vue.extend(popupBaseTpl)
var PopupContainerConstructor = Vue.extend(popupContainerTpl)
var containerInBody = document.body.getElementsByClassName('vc-popup-conatiner')
Router.initialParam('popup')
if (containerInBody.length === 0) {
popupContainer = new PopupContainerConstructor({
el: document.createElement('div')
})
document.body.appendChild(popupContainer.$el)
} else {
popupContainer = containerInBody[0].__vue__
}
// TODO: 提供全局常用方法来实现引用解耦
Vue.prototype.$popup = {}
Vue.prototype.$popup.prototype = {
$closeTop () {
},
$getPopupCtrls () {
}
}
Vue.prototype.__popup__ = Popup = {
fromHashChange: false,
fromUpdateRouter: false,
popupInShowingNum: 0,
lastPageStatus: null,
open (vmBase, routerId) {
popupContainer.turnOn()
this.popupInShowingNum++
vmBase._beforeMount()
popupContainer.addPopup(vmBase.$el)
vmBase._afterMount()
this.updateRouter(routerId)
this.lastPageStatus = 'showing'
},
close (routerId) {
var vmBase = vmBaseOfRouterId[routerId]
this.lastPageStatus = 'closing'
vmBase && vmBase._leave(() => {
if (--this.popupInShowingNum === 0) {
popupContainer.turnOff()
this.lastPageStatus = 'closed'
}
this.destroyPopup(routerId)
})
},
register (routerId, trigger) {
constructorOfRouterId[routerId] = trigger
},
createPopup (config, runtimeConfig, routerId) {
config.runtimeConfig = runtimeConfig
config.e = runtimeConfig.propsData.e
return (vmBaseOfRouterId[routerId] = new PopupBaseConstructor({
el: document.createElement('div'),
propsData: config
}))
},
destroyPopup (routerId) {
var vmBase = vmBaseOfRouterId[routerId]
vmBaseOfRouterId[routerId] = undefined
vmBase.isShowing = false
popupContainer.removePopup(vmBase.$el)
vmBase.vmSlot.$destroy()
vmBase.$destroy()
},
updateRouter (popupName) {
if (this.fromHashChange) {
this.fromHashChange = false
return this.fromHashChange
}
var value = Router.getParamValue('popup')
if (value && value.split('/').pop() !== popupName) {
value += '/' + popupName
} else {
value = popupName
}
this.fromUpdateRouter = true
Router.parseHashCommand('&popup=' + value)
}
}
// 返回键
Router.listenParam('popup', {
onEnter (val) {
if (Popup.fromUpdateRouter) {
Popup.fromUpdateRouter = false
return Popup.fromUpdateRouter
}
var list = splitPopupValue(val)
var trigger = constructorOfRouterId[top(list)]
Popup.fromHashChange = true
trigger && trigger()
},
onLeave (val, oVal) {
var oList = splitPopupValue(oVal)
var list = splitPopupValue(val)
var oListTop = top(oList)
if (prev(list) !== oListTop) {
Popup.fromUpdateRouter = false
Popup.fromHashChange = false
Popup.close(oListTop)
}
},
onBack (val) {
}
})
// esc键
var ESC_KEY_CODE = 27
window.addEventListener('keyup', function (e) {
e.keyCode === ESC_KEY_CODE &&
Popup.lastPageStatus === 'showing' &&
Popup.popupInShowingNum > 0 &&
history.back()
})
}
export { Popup }
export default Popup