mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-06 03:57:59 +08:00
fix(Popup): teleport
This commit is contained in:
parent
7087922d18
commit
6995bcc8a3
@ -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,
|
||||||
|
@ -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);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
@ -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()}
|
||||||
</>
|
</>
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
Loading…
x
Reference in New Issue
Block a user