@mirari/mp-common
Version:
小程序公共库
160 lines (146 loc) • 3.46 kB
JavaScript
class ModalManager {
constructor(page = getCurrentPages()[getCurrentPages().length - 1], config = {
onShow: null,
onHide: null
}) {
this.page = page
this.config = config
this._init()
}
/**
* 初始化
*/
_init () {
this.stack = []
this.freeze = false // 锁定当前窗口,不再响应其他弹出请求
this.setData = this.page.setData.bind(this.page)
}
/**
* 取栈顶元素,不弹出
* @param {Array} stack 堆栈
*/
_getCurrentModal () {
return this.stack[this.stack.length - 1]
}
_getIndex (modal) {
return this.stack.indexOf(modal)
}
show (modal, freeze) {
if (this._getCurrentModal() === modal) {
return
}
if (this.freeze) {
return
}
const index = this._getIndex(modal)
// 若已存在堆栈中,则先删除
if (index !== -1) {
this.stack.splice(index, 1)
}
// 其他窗口隐藏
for (let item of this.stack) {
if (item.getVisible()) {
item._toggle(false)
}
}
// 入栈
this.stack.push(modal)
// 当前窗口显示
modal._toggle(true)
// 冻结当前窗口
this.freeze = freeze
if (this.config.onShow) {
this.config.onShow(this.stack)
}
}
hide (modal = this._getCurrentModal()) {
if (Array.isArray(modal)) {
for (let item of modal) {
this.hide(item)
}
} else {
// 隐藏该窗口
modal._toggle(false)
// 从堆栈中删除
const index = this._getIndex(modal)
if (index !== -1) {
this.stack.splice(index, 1)
// 当前窗口关闭时解冻
if (index === this.stack.length - 1) {
this.freeze = false
}
// 打开栈顶窗口
if (this.stack.length) {
this._getCurrentModal()._toggle(true)
}
}
if (this.config.onHide) {
this.config.onHide(this.stack)
}
}
}
hideAll () {
// 隐藏所有窗口
for (let item of this.stack) {
if (item.getVisible()) {
item._toggle(false)
}
}
// 清空栈
this.stack = []
this.freeze = false
if (this.config.onHide) {
this.config.onHide(this.stack)
}
}
// 根据id获得指定modal
getModal (id) {
for (let i = 0; i < this.stack; i++) {
if (this.stack[i].id === id) {
return this.stack[i]
}
}
const modalComponent = this.page.selectComponent(`#${id}`)
return modalComponent && modalComponent.$modal
}
}
class Modal {
constructor(modal, {page = getCurrentPages()[getCurrentPages().length - 1], propName = 'visible', mgrName = '$modalMgr'} = {}) {
Object.assign(this, {
page, // 当前页面
modal, // 当前模态窗口组件实例
mgrName, // page的模态窗口管理器属性名称
propName // visible属性名称
})
this.__init()
}
__init() {
this.setData = this.modal.setData.bind(this.modal)
}
_getModalMgr () {
const mgr = this.page[this.mgrName]
if (!mgr) {
console.log('页面尚未注册模态窗口管理器')
}
return mgr
}
// 切换显隐状态
_toggle (visible) {
this.setData({
[this.propName]: visible
})
}
getVisible () {
return this.modal.data[this.propName]
}
open (freeze) {
this._getModalMgr().show(this, freeze)
}
close () {
this._getModalMgr().hide(this)
}
}
export {
ModalManager,
Modal
}