mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-05-23 15:09:16 +08:00
[Improvement] Popup: add click-overlay event (#647)
This commit is contained in:
parent
c0f870ceb9
commit
5d25d7aff9
@ -49,3 +49,9 @@ Use `position` prop to set popup display position
|
|||||||
| transition | Transition | `String` | `popup-slide` | - |
|
| transition | Transition | `String` | `popup-slide` | - |
|
||||||
| prevent-scroll | Prevent background scroll | `Boolean` | `false` | - |
|
| prevent-scroll | Prevent background scroll | `Boolean` | `false` | - |
|
||||||
| get-container | Return the mount node for Popup | `Function` | - | `() => HTMLElement` |
|
| get-container | Return the mount node for Popup | `Function` | - | `() => HTMLElement` |
|
||||||
|
|
||||||
|
### Event
|
||||||
|
|
||||||
|
| Event | Description | Arguments |
|
||||||
|
|-----------|-----------|-----------|
|
||||||
|
| click-overlay | Triggered when click overlay | - |
|
||||||
|
@ -49,3 +49,9 @@ export default {
|
|||||||
| transition | transition 名称 | `String` | `popup-slide` | - |
|
| transition | transition 名称 | `String` | `popup-slide` | - |
|
||||||
| prevent-scroll | 是否防止滚动穿透 | `Boolean` | `false` | - |
|
| prevent-scroll | 是否防止滚动穿透 | `Boolean` | `false` | - |
|
||||||
| get-container | 指定弹出层挂载的 HTML 节点 | `Function` | - | `() => HTMLElement` |
|
| get-container | 指定弹出层挂载的 HTML 节点 | `Function` | - | `() => HTMLElement` |
|
||||||
|
|
||||||
|
### Event
|
||||||
|
|
||||||
|
| 事件名 | 说明 | 参数 |
|
||||||
|
|-----------|-----------|-----------|
|
||||||
|
| click-overlay | 点击蒙层时触发 | - |
|
||||||
|
@ -113,7 +113,7 @@ export default {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (this.overlay) {
|
if (this.overlay) {
|
||||||
manager.openModal(this, {
|
manager.open(this, {
|
||||||
id: this._popupId,
|
id: this._popupId,
|
||||||
dom: this.$el,
|
dom: this.$el,
|
||||||
zIndex: context.plusKey('zIndex'),
|
zIndex: context.plusKey('zIndex'),
|
||||||
@ -146,7 +146,7 @@ export default {
|
|||||||
},
|
},
|
||||||
|
|
||||||
doAfterClose() {
|
doAfterClose() {
|
||||||
manager.closeModal(this._popupId);
|
manager.close(this._popupId);
|
||||||
|
|
||||||
if (this.lockOnScroll) {
|
if (this.lockOnScroll) {
|
||||||
document.body.classList.remove('van-overflow-hidden');
|
document.body.classList.remove('van-overflow-hidden');
|
||||||
|
@ -2,68 +2,48 @@ import Vue from 'vue';
|
|||||||
import Modal from './Modal';
|
import Modal from './Modal';
|
||||||
import context from './context';
|
import context from './context';
|
||||||
|
|
||||||
const modalDefaultConfig = {
|
const defaultConfig = {
|
||||||
className: '',
|
className: '',
|
||||||
customStyle: {}
|
customStyle: {}
|
||||||
};
|
};
|
||||||
|
|
||||||
const manager = {
|
export default {
|
||||||
getModal() {
|
open(vm, config) {
|
||||||
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) {
|
|
||||||
const { id, dom } = config;
|
const { id, dom } = config;
|
||||||
const exist = context.stack.some(item => item.id === id);
|
const exist = context.stack.some(item => item.id === id);
|
||||||
|
|
||||||
/* istanbul ignore next */
|
/* istanbul ignore next */
|
||||||
if (!exist) {
|
if (!exist) {
|
||||||
const targetNode = dom && dom.parentNode && dom.parentNode.nodeType !== 11 ? dom.parentNode : document.body;
|
const targetNode = dom && dom.parentNode && dom.parentNode.nodeType !== 11 ? dom.parentNode : document.body;
|
||||||
context.stack.push({ instance, id, config, targetNode });
|
context.stack.push({ vm, id, config, targetNode });
|
||||||
this.updateModal();
|
this.update();
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|
||||||
closeModal(id) {
|
close(id) {
|
||||||
const { stack } = context;
|
const { stack } = context;
|
||||||
|
|
||||||
if (stack.length) {
|
if (stack.length) {
|
||||||
if (context.top.id === id) {
|
if (context.top.id === id) {
|
||||||
stack.pop();
|
stack.pop();
|
||||||
this.updateModal();
|
this.update();
|
||||||
} else {
|
} else {
|
||||||
context.stack = stack.filter(item => item.id !== id);
|
context.stack = stack.filter(item => item.id !== id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
updateModal() {
|
update() {
|
||||||
const modal = this.getModal();
|
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) {
|
if (modal.$el.parentNode) {
|
||||||
modal.visible = false;
|
modal.visible = false;
|
||||||
@ -74,12 +54,21 @@ const manager = {
|
|||||||
|
|
||||||
targetNode.appendChild(modal.$el);
|
targetNode.appendChild(modal.$el);
|
||||||
Object.assign(modal, {
|
Object.assign(modal, {
|
||||||
...modalDefaultConfig,
|
...defaultConfig,
|
||||||
...config,
|
...config,
|
||||||
visible: true
|
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;
|
|
||||||
|
@ -100,9 +100,8 @@ describe('Popup', () => {
|
|||||||
|
|
||||||
expect(wrapper.hasClass('van-popup')).to.be.true;
|
expect(wrapper.hasClass('van-popup')).to.be.true;
|
||||||
|
|
||||||
const modal = document.querySelector('.van-modal');
|
|
||||||
|
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
|
const modal = document.querySelector('.van-modal');
|
||||||
triggerTouch(modal, 'touchstart', 0, 0);
|
triggerTouch(modal, 'touchstart', 0, 0);
|
||||||
triggerTouch(modal, 'touchmove', 0, 10);
|
triggerTouch(modal, 'touchmove', 0, 10);
|
||||||
triggerTouch(modal, 'touchmove', 0, 30);
|
triggerTouch(modal, 'touchmove', 0, 30);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user