fix(Popup): teleport

This commit is contained in:
chenjiahan 2020-07-06 15:12:56 +08:00
parent 7087922d18
commit 6995bcc8a3
3 changed files with 43 additions and 67 deletions

View File

@ -8,7 +8,6 @@ import { getScroller } from '../../utils/dom/scroll';
// Mixins // Mixins
import { TouchMixin } from '../touch'; import { TouchMixin } from '../touch';
import { PortalMixin } from '../portal';
import { CloseOnPopstateMixin } from '../close-on-popstate'; import { CloseOnPopstateMixin } from '../close-on-popstate';
export const popupMixinProps = { export const popupMixinProps = {
@ -20,6 +19,8 @@ export const popupMixinProps = {
overlayStyle: Object, overlayStyle: Object,
// overlay custom class name // overlay custom class name
overlayClass: String, overlayClass: String,
// teleport
getContainer: [String, Function],
// whether to close popup when click overlay // whether to close popup when click overlay
closeOnClickOverlay: Boolean, closeOnClickOverlay: Boolean,
// z-index // z-index
@ -41,7 +42,6 @@ export function PopupMixin(options = {}) {
mixins: [ mixins: [
TouchMixin, TouchMixin,
CloseOnPopstateMixin, CloseOnPopstateMixin,
PortalMixin({}),
], ],
props: popupMixinProps, props: popupMixinProps,

View File

@ -1,47 +0,0 @@
function getElement(selector) {
if (typeof selector === 'string') {
return document.querySelector(selector);
}
return selector();
}
export function PortalMixin({ ref, afterPortal }) {
return {
props: {
getContainer: [String, Function],
},
watch: {
getContainer: 'portal',
},
mounted() {
if (this.getContainer) {
this.portal();
}
},
methods: {
portal() {
const { getContainer } = this;
const el = ref ? this.$refs[ref] : this.$el;
let container;
if (getContainer) {
container = getElement(getContainer);
} else if (this.$parent) {
container = this.$parent.$el;
}
if (container && container !== el.parentNode) {
container.appendChild(el);
}
if (afterPortal) {
afterPortal.call(this);
}
},
},
};
}

View File

@ -1,5 +1,5 @@
import { Transition } from 'vue'; import { Teleport, Transition } from 'vue';
import { createNamespace, isDef } from '../utils'; import { createNamespace, isDef, isFunction } from '../utils';
import { PopupMixin } from '../mixins/popup'; import { PopupMixin } from '../mixins/popup';
import Icon from '../icon'; import Icon from '../icon';
import Overlay from '../overlay'; import Overlay from '../overlay';
@ -48,25 +48,28 @@ export default createComponent({
this.onClosed = createEmitter('closed'); this.onClosed = createEmitter('closed');
}, },
render() { methods: {
const { round, position, duration } = this; genOverlay() {
const isCenter = position === 'center'; if (this.overlay) {
return <Overlay show={this.show} onClick={this.onClickOverlay} />;
}
},
const transitionName = genPopup() {
this.transition || const { round, position, duration } = this;
(isCenter ? 'van-fade' : `van-popup-slide-${position}`); const isCenter = position === 'center';
const style = {}; const transitionName =
if (isDef(duration)) { this.transition ||
const key = isCenter ? 'animationDuration' : 'transitionDuration'; (isCenter ? 'van-fade' : `van-popup-slide-${position}`);
style[key] = `${duration}s`;
}
return ( const style = {};
<> if (isDef(duration)) {
{this.overlay && ( const key = isCenter ? 'animationDuration' : 'transitionDuration';
<Overlay show={this.show} onClick={this.onClickOverlay} /> style[key] = `${duration}s`;
)} }
return (
<Transition <Transition
name={transitionName} name={transitionName}
onAfterEnter={this.onOpened} onAfterEnter={this.onOpened}
@ -98,6 +101,26 @@ export default createComponent({
</div> </div>
) : null} ) : null}
</Transition> </Transition>
);
},
},
render() {
const { getContainer } = this;
if (getContainer) {
const to = isFunction(getContainer) ? getContainer() : getContainer;
return (
<Teleport to={to}>
{this.genOverlay()}
{this.genPopup()}
</Teleport>
);
}
return (
<>
{this.genOverlay()}
{this.genPopup()}
</> </>
); );
}, },