Vue3中如何确保仅在目标容器挂载后再使用Teleport?
解决Vue Teleport目标容器晚挂载导致的报错问题
通过
v-if控制渲染时机
直接用v-if判断目标容器是否存在,只有当容器出现后才渲染<Teleport>组件。如果容器是异步加载的,可以用轮询来持续检测:<template> <Teleport v-if="targetExists" to="#teleport-target"> <div>需要Teleport的内容</div> </Teleport> </template> <script setup> import { ref, onMounted, onUnmounted } from 'vue' const targetExists = ref(false) let checkTimer = null onMounted(() => { // 初始化检查一次 targetExists.value = !!document.getElementById('teleport-target') // 没找到就启动轮询 if (!targetExists.value) { checkTimer = setInterval(() => { const target = document.getElementById('teleport-target') if (target) { targetExists.value = true clearInterval(checkTimer) } }, 100) } }) onUnmounted(() => { // 组件卸载时清理定时器 if (checkTimer) clearInterval(checkTimer) }) </script>动态绑定Teleport目标
把to属性绑定为响应式变量,用DOM变化监听(MutationObserver)检测目标容器,一旦出现就更新目标值:<template> <Teleport :to="teleportTarget"> <div>需要Teleport的内容</div> </Teleport> </template> <script setup> import { ref, onMounted, onUnmounted } from 'vue' const teleportTarget = ref(null) let observer = null const checkTarget = () => { const target = document.getElementById('teleport-target') if (target) { teleportTarget.value = target observer?.disconnect() // 找到目标后停止监听 } } onMounted(() => { checkTarget() // 监听body下的DOM变化,适配容器动态生成的场景 observer = new MutationObserver(checkTarget) observer.observe(document.body, { childList: true, subtree: true }) }) onUnmounted(() => { observer?.disconnect() }) </script>组件通信同步挂载状态
如果目标容器是项目内其他组件生成的,可以在容器组件挂载后触发事件,通知Teleport组件开始渲染:<!-- 父组件 --> <template> <!-- 生成目标容器的组件 --> <TargetContainer @container-ready="isContainerReady = true" /> <Teleport v-if="isContainerReady" to="#teleport-target"> <div>需要Teleport的内容</div> </Teleport> </template> <script setup> import { ref } from 'vue' import TargetContainer from './TargetContainer.vue' const isContainerReady = ref(false) </script> <!-- TargetContainer.vue --> <template> <div id="teleport-target"></div> </template> <script setup> import { onMounted } from 'vue' const emit = defineEmits(['container-ready']) onMounted(() => { // 容器挂载后通知父组件 emit('container-ready') }) </script>
内容的提问来源于stack exchange,提问作者Mysterywood
相关产品推荐
相关产品推荐

