From 5d25d7aff9868a9b2265163e77346d7a2b841b40 Mon Sep 17 00:00:00 2001 From: neverland Date: Sat, 24 Feb 2018 15:22:41 +0800 Subject: [PATCH] [Improvement] Popup: add click-overlay event (#647) --- docs/markdown/en-US/popup.md | 6 +++ docs/markdown/zh-CN/popup.md | 6 +++ packages/mixins/popup/index.js | 4 +- packages/mixins/popup/manager.js | 71 ++++++++++++++------------------ test/specs/popup.spec.js | 3 +- 5 files changed, 45 insertions(+), 45 deletions(-) diff --git a/docs/markdown/en-US/popup.md b/docs/markdown/en-US/popup.md index 4c7474c94..ac2f1f7c3 100644 --- a/docs/markdown/en-US/popup.md +++ b/docs/markdown/en-US/popup.md @@ -49,3 +49,9 @@ Use `position` prop to set popup display position | transition | Transition | `String` | `popup-slide` | - | | prevent-scroll | Prevent background scroll | `Boolean` | `false` | - | | get-container | Return the mount node for Popup | `Function` | - | `() => HTMLElement` | + +### Event + +| Event | Description | Arguments | +|-----------|-----------|-----------| +| click-overlay | Triggered when click overlay | - | diff --git a/docs/markdown/zh-CN/popup.md b/docs/markdown/zh-CN/popup.md index 47b33a47b..009e537ae 100644 --- a/docs/markdown/zh-CN/popup.md +++ b/docs/markdown/zh-CN/popup.md @@ -49,3 +49,9 @@ export default { | transition | transition 名称 | `String` | `popup-slide` | - | | prevent-scroll | 是否防止滚动穿透 | `Boolean` | `false` | - | | get-container | 指定弹出层挂载的 HTML 节点 | `Function` | - | `() => HTMLElement` | + +### Event + +| 事件名 | 说明 | 参数 | +|-----------|-----------|-----------| +| click-overlay | 点击蒙层时触发 | - | diff --git a/packages/mixins/popup/index.js b/packages/mixins/popup/index.js index 399f38edf..24d7f6ac0 100644 --- a/packages/mixins/popup/index.js +++ b/packages/mixins/popup/index.js @@ -113,7 +113,7 @@ export default { } if (this.overlay) { - manager.openModal(this, { + manager.open(this, { id: this._popupId, dom: this.$el, zIndex: context.plusKey('zIndex'), @@ -146,7 +146,7 @@ export default { }, doAfterClose() { - manager.closeModal(this._popupId); + manager.close(this._popupId); if (this.lockOnScroll) { document.body.classList.remove('van-overflow-hidden'); diff --git a/packages/mixins/popup/manager.js b/packages/mixins/popup/manager.js index bf2e1c104..07e878afe 100644 --- a/packages/mixins/popup/manager.js +++ b/packages/mixins/popup/manager.js @@ -2,68 +2,48 @@ import Vue from 'vue'; import Modal from './Modal'; import context from './context'; -const modalDefaultConfig = { +const defaultConfig = { className: '', customStyle: {} }; -const manager = { - getModal() { - let { modal } = context; - - if (!modal) { - const ModalConstructor = Vue.extend(Modal); - modal = new ModalConstructor({ - el: document.createElement('div') - }); - modal.$on('click', () => { - manager.onClickOverlay(); - }); - - context.modal = modal; - } - - return modal; - }, - - // close popup when click modal && closeOnClickOverlay is true - onClickOverlay() { - const { top } = context; - if (top) { - const { instance } = top; - if (instance && instance.closeOnClickOverlay) { - instance.close(); - } - } - }, - - openModal(instance, config) { +export default { + open(vm, config) { const { id, dom } = config; const exist = context.stack.some(item => item.id === id); /* istanbul ignore next */ if (!exist) { const targetNode = dom && dom.parentNode && dom.parentNode.nodeType !== 11 ? dom.parentNode : document.body; - context.stack.push({ instance, id, config, targetNode }); - this.updateModal(); + context.stack.push({ vm, id, config, targetNode }); + this.update(); }; }, - closeModal(id) { + close(id) { const { stack } = context; if (stack.length) { if (context.top.id === id) { stack.pop(); - this.updateModal(); + this.update(); } else { context.stack = stack.filter(item => item.id !== id); } } }, - updateModal() { - const modal = this.getModal(); + update() { + let { modal } = context; + + if (!modal) { + modal = new (Vue.extend(Modal))({ + el: document.createElement('div') + }); + modal.$on('click', this.onClick); + + context.modal = modal; + } if (modal.$el.parentNode) { modal.visible = false; @@ -74,12 +54,21 @@ const manager = { targetNode.appendChild(modal.$el); Object.assign(modal, { - ...modalDefaultConfig, + ...defaultConfig, ...config, visible: true }); } + }, + + // close popup when click modal && closeOnClickOverlay is true + onClick() { + if (context.top) { + const { vm } = context.top; + if (vm) { + vm.$emit('click-overlay'); + vm.closeOnClickOverlay && vm.close(); + } + } } }; - -export default manager; diff --git a/test/specs/popup.spec.js b/test/specs/popup.spec.js index 7f13782c6..1cef0261c 100644 --- a/test/specs/popup.spec.js +++ b/test/specs/popup.spec.js @@ -100,9 +100,8 @@ describe('Popup', () => { expect(wrapper.hasClass('van-popup')).to.be.true; - const modal = document.querySelector('.van-modal'); - setTimeout(() => { + const modal = document.querySelector('.van-modal'); triggerTouch(modal, 'touchstart', 0, 0); triggerTouch(modal, 'touchmove', 0, 10); triggerTouch(modal, 'touchmove', 0, 30);