В зависимости от состояния загрузки иногда целевой контейнер <Teleport /> монтируется позже, чем монтируется содержимое, что приводит к ошибке Vue.
[Vue warn]: Invalid Teleport target on mount: null.
Как гарантировать, что Vue пытается телепортироваться только после того, как контейнер был смонтирован, или телепортируется только в том случае, если контейнер присутствует?





Во-первых, мы создаем способ отслеживать, смонтирован ли наш целевой контейнер. Мы хотим, чтобы это было глобально доступно, чтобы компоненты из других частей дерева рендеринга могли получить доступ к состоянию.
// useTeleportTarget.ts
const teleportMap: Record<string, Ref<HTMLElement | undefined>> = {}
export function useTeleportTarget(elementId: string) {
if (!teleportMap[elementId])
teleportMap[elementId] = ref<HTMLElement>()
return teleportMap[elementId]
}
Затем мы создаем простой в использовании компонент Teleport, который накладывается на исходный API. Этот компонент помогает нам определить, смонтирован ли контейнер, прежде чем пытаться телепортироваться.
// BetterTeleport.vue
<script setup lang = "ts">
import { useTeleportTarget } from '@/helpers/useTeleportTarget'
const props = defineProps<{
to: string
}>()
const target = useTeleportTarget(props.to)
</script>
<template>
<Teleport v-if = "target" :to = "`#${to}`">
<slot />
</Teleport>
</template>
Используя новую настройку:
// Container.vue
<script setup>
// We register our container target with the element ID
const myContainer = useTeleportTarget('my-container')
// Not important, only to demonstrate this container may or may not be mounted
const showTeleportContainer = ref(true)
</script>
<template>
<div
v-if = "showTeleportContainer"
id = "my-container"
ref = "myContainer"
></div>
</template>
При этом телепортация должна работать всегда!
// FarAwayContent.vue
<template>
<BetterTeleport to = "my-container">
I love my swamp!
</BetterTeleport>
</template>
Это может быть проблема XY. Обычно showTeleportContainer может быть зависимостью на уровне страницы или блока, и иерархия компонентов, которые зависят от нее, не будет смонтирована, пока она не станет доступной, например. через ожидание. Не сильно отличается от любого другого хранилища, например данных хранилища.