mirror of
https://gitee.com/vant-contrib/vant.git
synced 2025-04-30 13:16:34 +08:00
56 lines
1.2 KiB
TypeScript
56 lines
1.2 KiB
TypeScript
import Vue, { PropType } from 'vue';
|
|
import { GetContainer } from './popup/type';
|
|
|
|
type PortalMixinOptions = {
|
|
ref?: string;
|
|
afterPortal?: () => void;
|
|
};
|
|
|
|
function getElement(selector: string | GetContainer): Element | null {
|
|
if (typeof selector === 'string') {
|
|
return document.querySelector(selector);
|
|
}
|
|
|
|
return selector();
|
|
}
|
|
|
|
export function PortalMixin({ ref, afterPortal }: PortalMixinOptions) {
|
|
return Vue.extend({
|
|
props: {
|
|
getContainer: [String, Function] as (PropType<string | GetContainer>)
|
|
},
|
|
|
|
watch: {
|
|
getContainer: 'portal'
|
|
},
|
|
|
|
mounted() {
|
|
if (this.getContainer) {
|
|
this.portal();
|
|
}
|
|
},
|
|
|
|
methods: {
|
|
portal() {
|
|
const { getContainer } = this;
|
|
const el = ref ? this.$refs[ref] as HTMLElement : 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);
|
|
}
|
|
}
|
|
}
|
|
});
|
|
}
|