diff --git a/packages/action-sheet/index.tsx b/packages/action-sheet/index.tsx index 3c88d59c4..24cd0da86 100644 --- a/packages/action-sheet/index.tsx +++ b/packages/action-sheet/index.tsx @@ -146,6 +146,7 @@ ActionSheet.props = { title: String, actions: Array, cancelText: String, + getContainer: [String, Function], closeOnClickAction: Boolean, safeAreaInsetBottom: Boolean, overlay: { diff --git a/packages/mixins/popup/index.js b/packages/mixins/popup/index.js index dd3a2dc28..fccf74476 100644 --- a/packages/mixins/popup/index.js +++ b/packages/mixins/popup/index.js @@ -1,11 +1,21 @@ import { context } from './context'; import { TouchMixin } from '../touch'; +import { PortalMixin } from '../portal'; import { on, off, preventDefault } from '../../utils/dom/event'; import { openOverlay, closeOverlay, updateOverlay } from './overlay'; import { getScrollEventTarget } from '../../utils/dom/scroll'; export const PopupMixin = { - mixins: [TouchMixin], + mixins: [ + TouchMixin, + PortalMixin({ + afterPortal() { + if (this.overlay) { + updateOverlay(); + } + } + }) + ], props: { // whether to show popup @@ -20,8 +30,6 @@ export const PopupMixin = { closeOnClickOverlay: Boolean, // z-index zIndex: [String, Number], - // return the mount node for popup - getContainer: [String, Function], // prevent body scroll lockScroll: { type: Boolean, @@ -54,19 +62,12 @@ export const PopupMixin = { this.$emit(type); }, - getContainer() { - this.move(); - }, - overlay() { this.renderOverlay(); } }, mounted() { - if (this.getContainer) { - this.move(); - } if (this.value) { this.open(); } @@ -138,28 +139,6 @@ export const PopupMixin = { this.$emit('input', false); }, - move() { - let container; - const { getContainer } = this; - - if (getContainer) { - container = - typeof getContainer === 'string' - ? document.querySelector(getContainer) - : getContainer(); - } else if (this.$parent) { - container = this.$parent.$el; - } - - if (container && container !== this.$el.parentNode) { - container.appendChild(this.$el); - } - - if (this.overlay) { - updateOverlay(); - } - }, - onTouchMove(event) { this.touchMove(event); const direction = this.deltaY > 0 ? '10' : '01'; diff --git a/packages/mixins/portal.js b/packages/mixins/portal.js new file mode 100644 index 000000000..96f586b1b --- /dev/null +++ b/packages/mixins/portal.js @@ -0,0 +1,48 @@ +function getElement(selector) { + if (typeof selector === 'string') { + return document.querySelector(selector); + } + + return selector(); +} + +export function PortalMixin({ afterPortal }) { + return { + props: { + getContainer: [String, Function] + }, + + watch: { + getContainer() { + this.portal(); + } + }, + + mounted() { + if (this.getContainer) { + this.portal(); + } + }, + + methods: { + portal() { + const { getContainer } = this; + + let container; + if (getContainer) { + container = getElement(getContainer); + } else if (this.$parent) { + container = this.$parent.$el; + } + + if (container && container !== this.$el.parentNode) { + container.appendChild(this.$el); + } + + if (afterPortal) { + afterPortal.call(this); + } + } + } + }; +} diff --git a/packages/notify/Notify.tsx b/packages/notify/Notify.tsx index e3d8858a2..c6e883d16 100644 --- a/packages/notify/Notify.tsx +++ b/packages/notify/Notify.tsx @@ -58,6 +58,7 @@ Notify.props = { ...PopupMixin.props, className: null as any, message: [String, Number], + getContainer: [String, Function], color: { type: String, default: WHITE