diff --git a/docs/markdown/en-US/popup.md b/docs/markdown/en-US/popup.md
index 5e14339c6..598bf31a5 100644
--- a/docs/markdown/en-US/popup.md
+++ b/docs/markdown/en-US/popup.md
@@ -43,6 +43,8 @@ Use `position` prop to set popup display position
| overlay | Whether to show overlay | `Boolean` | `true` | - |
| lockOnScroll | Lock body scroll | `Boolean` | `false` | - |
| position | Position | `String` | - | `top` `bottom` `right` `left` |
+| overlayClass | Custom overlay class | `String` | `` | - |
+| overlayStyle | Custom overlay style | `Object` | `` | - |
| closeOnClickOverlay | Close popup when click overlay | `Boolean` | `true` | - |
| transition | Transition | `String` | `popup-slide` | - |
| preventScroll | Prevent background scroll | `Boolean` | `false` | - |
diff --git a/docs/markdown/zh-CN/popup.md b/docs/markdown/zh-CN/popup.md
index 7492131b1..905082121 100644
--- a/docs/markdown/zh-CN/popup.md
+++ b/docs/markdown/zh-CN/popup.md
@@ -40,9 +40,11 @@ export default {
| 参数 | 说明 | 类型 | 默认值 | 可选值 |
|-----------|-----------|-----------|-------------|-------------|
| v-model | 当前组件是否显示 | `Boolean` | `false` | - |
-| overlay | 是否显示背景遮罩层 | `Boolean` | `true` | - |
+| overlay | 是否显示背景蒙层 | `Boolean` | `true` | - |
| lockOnScroll | 背景是否跟随滚动 | `Boolean` | `false` | - |
-| position | 弹出层位置 | `String` | - | `top` `bottom` `right` `left` |
-| closeOnClickOverlay | 点击遮罩层是否关闭弹出层 | `Boolean` | `true` | - |
-| transition | 弹出层的`transition` | `String` | `popup-slide` | - |
+| position | Popup 位置 | `String` | - | `top` `bottom` `right` `left` |
+| overlayClass | 自定义蒙层 class | `String` | `` | - |
+| overlayStyle | 自定义蒙层样式 | `Object` | `` | - |
+| closeOnClickOverlay | 点击蒙层是否关闭 Popup | `Boolean` | `true` | - |
+| transition | transition 名称 | `String` | `popup-slide` | - |
| preventScroll | 是否防止滚动穿透 | `Boolean` | `false` | - |
diff --git a/docs/src/components/DemoList.vue b/docs/src/components/DemoList.vue
index 6ff02a794..153bd0a69 100644
--- a/docs/src/components/DemoList.vue
+++ b/docs/src/components/DemoList.vue
@@ -49,6 +49,8 @@ export default {
methods: {
switchLang(lang) {
+ const from = lang === 'zh-CN' ? 'en-US' : 'zh-CN';
+ this.$router.push(this.$route.path.replace(from, lang));
setLang(lang);
}
}
diff --git a/packages/mixins/popup/Modal.vue b/packages/mixins/popup/Modal.vue
new file mode 100644
index 000000000..a9c663a73
--- /dev/null
+++ b/packages/mixins/popup/Modal.vue
@@ -0,0 +1,30 @@
+
+
+
+
+
diff --git a/packages/mixins/popup/index.js b/packages/mixins/popup/index.js
index 38c69e677..522a93e86 100644
--- a/packages/mixins/popup/index.js
+++ b/packages/mixins/popup/index.js
@@ -112,9 +112,10 @@ export default {
id: this._popupId,
zIndex: context.plusKeyByOne('zIndex'),
dom: this.$el,
- extraClass: this.overlayClass,
- extraStyle: this.overlayStyle
+ className: this.overlayClass,
+ customStyle: this.overlayStyle
});
+
if (this.lockOnScroll) {
document.body.classList.add('van-overflow-hidden');
}
diff --git a/packages/mixins/popup/popup-context.js b/packages/mixins/popup/popup-context.js
index 81035f451..14039e53c 100644
--- a/packages/mixins/popup/popup-context.js
+++ b/packages/mixins/popup/popup-context.js
@@ -2,14 +2,14 @@ const PopupContext = {
idSeed: 1,
zIndex: 2000,
instances: {},
- modalStack: [],
+ stack: [],
plusKeyByOne(key) {
return this[key]++;
},
- get topModal() {
- return this.modalStack[this.modalStack.length - 1];
+ get top() {
+ return this.stack[this.stack.length - 1];
}
};
diff --git a/packages/mixins/popup/popup-manager.js b/packages/mixins/popup/popup-manager.js
index 4da186d7f..fc632526e 100644
--- a/packages/mixins/popup/popup-manager.js
+++ b/packages/mixins/popup/popup-manager.js
@@ -1,17 +1,22 @@
+import Vue from 'vue';
+import Modal from './Modal';
import context from './popup-context';
+const modalDefaultConfig = {
+ className: '',
+ customStyle: {}
+};
+
const PopupManager = {
getModal() {
let { modal } = context;
if (!modal) {
- modal = document.createElement('div');
- modal.classList.add('van-modal');
- modal.addEventListener('touchmove', event => {
- event.preventDefault();
- event.stopPropagation();
+ const ModalConstructor = Vue.extend(Modal);
+ modal = new ModalConstructor({
+ el: document.createElement('div')
});
- modal.addEventListener('click', () => {
+ modal.$on('click', () => {
PopupManager.handleOverlayClick();
});
@@ -23,52 +28,56 @@ const PopupManager = {
// close popup when click modal && closeOnClickOverlay is true
handleOverlayClick() {
- const { topModal } = context;
- if (topModal) {
- const instance = context.instances[topModal.id];
+ const { top } = context;
+ if (top) {
+ const instance = context.instances[top.id];
if (instance && instance.closeOnClickOverlay) {
instance.close();
}
}
},
- openModal({ id, zIndex, dom, extraClass, extraStyle }) {
- const { modalStack } = context;
- const exist = modalStack.some(item => item.id === id);
+ openModal(config) {
+ const { id, dom } = config;
+ const exist = context.stack.some(item => item.id === id);
if (!exist) {
- const modal = this.getModal();
- if (extraClass) {
- modal.classList.add(extraClass);
- }
- if (extraStyle) {
- modal.style.cssText = `${modal.style.cssText} ${extraStyle}`;
- }
- modal.style.zIndex = zIndex;
-
- const parentNode = dom && dom.parentNode && dom.parentNode.nodeType !== 11 ? dom.parentNode : document.body;
- parentNode.appendChild(modal);
- modalStack.push({ id, zIndex, parentNode });
+ const targetNode = dom && dom.parentNode && dom.parentNode.nodeType !== 11 ? dom.parentNode : document.body;
+ context.stack.push({ id, config, targetNode });
+ this.updateModal();
};
},
closeModal(id) {
- const { modalStack } = context;
+ const { stack } = context;
- if (modalStack.length) {
- if (context.topModal.id === id) {
- const modal = this.getModal();
- modalStack.pop();
- modal.parentNode.removeChild(modal);
- if (modalStack.length) {
- const { topModal } = context;
- modal.style.zIndex = topModal.zIndex;
- topModal.parentNode.appendChild(modal);
- }
+ if (stack.length) {
+ if (context.top.id === id) {
+ stack.pop();
+ this.updateModal();
} else {
- context.modalStack = modalStack.filter(item => item.id !== id);
+ context.stack = stack.filter(item => item.id !== id);
}
}
+ },
+
+ updateModal() {
+ const modal = this.getModal();
+ const el = modal.$el;
+
+ if (el.parentNode) {
+ el.parentNode.removeChild(el);
+ }
+
+ if (context.top) {
+ const { targetNode, config } = context.top;
+
+ targetNode.appendChild(el);
+ Object.assign(modal, {
+ ...modalDefaultConfig,
+ ...config
+ });
+ }
}
};