根据加载状态,有时
<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>