Vue3 Teleport实战:5个高级Portal应用场景解析
1. 基础模态框实现
创建可复用的模态框组件:
<!-- Modal.vue -->
<template>
<Teleport to="body">
<div class="modal-mask" v-if="show">
<div class="modal-container">
<slot></slot>
<button @click="$emit('close')">关闭</button>
</div>
</div>
</Teleport>
</template>
<script setup>
defineProps(['show'])
defineEmits(['close'])
</script>
<style scoped>
.modal-mask {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0,0,0,0.5);
display: flex;
justify-content: center;
align-items: center;
}
</style>
2. 全局通知系统
实现跨组件层级的通知:
<!-- Notification.vue -->
<template>
<Teleport to="#notifications">
<div class="notification" :class="type">
{{ message }}
</div>
</Teleport>
</template>
<!-- App.vue -->
<template>
<div id="app">
<div id="notifications"></div>
<!-- 其他内容 -->
</div>
</template>
<!-- 使用示例 -->
<Notification
v-if="showNotification"
message="操作成功"
type="success"
/>
3. 解决z-index层级问题
处理嵌套组件的层级冲突:
<!-- Tooltip.vue -->
<template>
<div class="tooltip-wrapper">
<slot name="trigger"></slot>
<Teleport to="body">
<div
class="tooltip-content"
v-if="isVisible"
:style="contentStyle"
>
<slot name="content"></slot>
</div>
</Teleport>
</div>
</template>
4. 动态目标Teleport
根据条件选择渲染目标:
<template>
<Teleport :to="target">
<div class="floating-element">
<!-- 内容 -->
</div>
</Teleport>
</template>
<script setup>
const target = computed(() => {
return isMobile.value ? '#mobile-container' : '#desktop-container'
})
</script>
场景 | 传统方案 | Teleport方案 |
---|---|---|
模态框 | z-index管理复杂 | 自动挂载到body |
全局通知 | 依赖全局状态 | 组件化实现 |
工具提示 | 易被父容器裁剪 | 突破容器限制 |
5. 服务端渲染(SSR)兼容方案
确保SSR环境下Teleport正常工作:
<template>
<Teleport :to="isMounted ? '#modal-container' : null">
<ModalContent />
</Teleport>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const isMounted = ref(false)
onMounted(() => {
isMounted.value = true
// 确保目标容器存在
if (!document.getElementById('modal-container')) {
const div = document.createElement('div')
div.id = 'modal-container'
document.body.appendChild(div)
}
})
</script>
通过合理使用Teleport,可以解决Vue应用中复杂的DOM层级问题,创建更灵活、更可靠的组件架构。