♻️(component): [teleportWrapper]使用 mutation observer,确保即使在渲染目标元素前挂载了 teleportWrapper, 他也能正常工作

This commit is contained in:
sight 2022-09-10 21:55:56 +08:00
parent 77ff852aaa
commit b826124c92
2 changed files with 16 additions and 9 deletions

View File

@ -19,15 +19,22 @@ const props = withDefaults(defineProps<TeleportWrapperProps>(), {
const target = ref<Element | null>(null); const target = ref<Element | null>(null);
onMounted(() => { onMounted(() => {
if (!props.to) return; const observer = new MutationObserver((mutationList, observer) => {
for (const mutation of mutationList) {
if (mutation.type !== "childList") continue;
const el = document.querySelector(props.to); const el = document.querySelector(props.to);
if (el) { if (!el) continue;
target.value = el; target.value = el;
observer.disconnect();
break;
} }
});
observer.observe(document, { childList: true, subtree: true });
return () => observer.disconnect();
}); });
</script> </script>
<template> <template>
<Teleport :to="target" :disabled="!target || disabled"> <Teleport :to="target" v-if="target" :disabled="!target || disabled">
<slot></slot> <slot></slot>
</Teleport> </Teleport>
</template> </template>

View File

@ -1,12 +1,12 @@
import { App, Plugin } from "vue"; import { App, Component, Plugin } from "vue";
export type WithInstallType<T> = T & Plugin; export type WithInstallType<T> = T & Plugin;
export const withInstall = <T>(comp: T): T & Plugin => { export const withInstall = <T>(comp: T): T & Plugin => {
const component = comp as any; const component = comp as T & Component & Plugin;
component.install = (app: App) => { component.install = (app: App) => {
app.component(component.name, comp); app.component(component.name!, comp as T & Component & Plugin);
}; };
return component as T & Plugin; return component as T & Plugin;