Vue3 Teleport组件实战:5个高级DOM传送技巧
1. 基础模态框实现
创建全局可用的模态框:
<!-- Modal.vue -->
<template>
<Teleport to="body">
<div class="modal" v-if="show">
<slot></slot>
<button @click="$emit('close')">关闭</button>
</div>
</Teleport>
</template>
<script setup>
defineProps(['show'])
defineEmits(['close'])
</script>
<!-- 使用示例 -->
<Modal :show="showModal" @close="showModal = false">
<h2>标题</h2>
<p>内容...</p>
</Modal>
2. 多目标传送
根据条件传送到不同位置:
<template>
<Teleport :to="target">
<div class="notification">
{{ message }}
</div>
</Teleport>
</template>
<script setup>
const props = defineProps({
target: {
type: String,
default: '#notifications'
},
message: String
})
</script>
3. 与Transition组合
实现传送动画效果:
<Teleport to="body">
<Transition name="fade">
<div class="tooltip" v-if="show">
{{ content }}
</div>
</Transition>
</Teleport>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.3s;
}
.fade-enter-from, .fade-leave-to {
opacity: 0;
}
</style>
4. 动态传送目标
运行时切换传送目标:
<template>
<Teleport :to="mobileView ? '#mobile-menu' : '#desktop-menu'">
<NavigationMenu />
</Teleport>
</template>
<script setup>
import { ref, onMounted } from 'vue'
const mobileView = ref(false)
onMounted(() => {
const checkViewport = () => {
mobileView.value = window.innerWidth < 768
}
window.addEventListener('resize', checkViewport)
checkViewport()
})
</script>
技术 | Vue2实现方式 | Vue3 Teleport |
---|---|---|
跨DOM渲染 | 手动DOM操作 | 声明式API |
组件上下文 | 可能丢失 | 完全保留 |
动画支持 | 复杂 | 原生支持 |
5. 全屏加载指示器
创建全局加载状态:
<!-- LoadingIndicator.vue -->
<template>
<Teleport to="#app">
<div class="loading-overlay" v-if="loading">
<div class="spinner"></div>
<p>{{ message }}</p>
</div>
</Teleport>
</template>
<script setup>
defineProps({
loading: Boolean,
message: {
type: String,
default: '加载中...'
}
})
</script>
<!-- 使用示例 -->
<LoadingIndicator :loading="isLoading" message="数据加载中..." />
Teleport为Vue3开发者提供了强大的DOM控制能力,特别适合模态框、通知、菜单等需要突破组件层级限制的场景。