全屏弹窗、消息提示这类浮层如果渲染在当前组件内部,很容易被父级的 overflow、z-index 或 transform 影响。Teleport 让组件的逻辑归属不变,渲染产物却投递到 body 或任意挂载点上:to 属性指定目标选择器,disabled 属性还能随时取消投递。
它是 Vue 3 的内置组件,与 Transition、Suspense 一同构成现代化的覆盖层方案。用法上注意 to 属性必须是有效的 CSS 选择器字符串,目标元素要已存在;teleport 出去的内容仍属于原组件,事件、inject 上下文都不会断,用起来非常安全。
<template> <button @click="open = true">打开弹窗</button> <teleport to="body" :disabled="!open"> <div v-if="open" class="modal"> <p>我渲染在 body 下,不受父级样式影响。</p> <button @click="open = false">关闭</button> </div> </teleport> </template> <script setup> import { ref } from 'vue'; const open = ref(false); </script> <style scoped> .modal { position: fixed; inset: 0; display: grid; place-items: center; background: rgba(0,0,0,.4); } </style>