主题
Teleport组件
1. 基本概念
1.1 什么是Teleport
Teleport是Vue3提供的一个内置组件,允许我们将组件的一部分模板"传送"到当前组件DOM层次结构之外的DOM节点中。
1.2 主要用途
- 模态框(Modal)实现
- 弹出提示
- 悬浮菜单
- 全局通知
2. 基本用法
2.1 基础示例
vue
<template>
<div class="container">
<teleport to="body">
<div class="modal">
<!-- 模态框内容 -->
</div>
</teleport>
</div>
</template>
2.2 动态控制
vue
<template>
<button @click="showModal = true">打开模态框</button>
<teleport to="body">
<div v-if="showModal" class="modal">
<h2>模态框标题</h2>
<p>模态框内容</p>
<button @click="showModal = false">关闭</button>
</div>
</teleport>
</template>
3. 高级特性
3.1 多个目标
vue
<template>
<teleport to="#modal-container">
<modal-content />
</teleport>
<teleport to="#notification-container">
<notification-content />
</teleport>
</template>
3.2 条件传送
vue
<template>
<teleport to="body" :disabled="!shouldTeleport">
<modal-content />
</teleport>
</template>
<script>
export default {
data() {
return {
shouldTeleport: true
}
}
}
</script>
4. 实际应用场景
4.1 模态框组件
vue
<!-- Modal.vue -->
<template>
<teleport to="body">
<div v-if="modelValue" class="modal-overlay">
<div class="modal">
<div class="modal-header">
<slot name="header"></slot>
</div>
<div class="modal-body">
<slot></slot>
</div>
<div class="modal-footer">
<slot name="footer">
<button @click="$emit('update:modelValue', false)">关闭</button>
</slot>
</div>
</div>
</div>
</teleport>
</template>
4.2 通知系统
vue
<!-- Notification.vue -->
<template>
<teleport to="#notification-container">
<transition-group name="notification">
<div
v-for="notice in notices"
:key="notice.id"
class="notification"
>
{{ notice.message }}
</div>
</transition-group>
</teleport>
</template>
5. 性能优化
5.1 按需传送
vue
<template>
<teleport to="body" v-if="shouldRender">
<heavy-component />
</teleport>
</template>
5.2 动态目标
vue
<script>
export default {
data() {
return {
teleportTarget: '#app'
}
},
mounted() {
// 根据条件动态改变传送目标
this.teleportTarget = this.isMobile ? '#mobile-container' : '#desktop-container'
}
}
</script>
6. 最佳实践
6.1 组件封装
vue
<!-- BaseModal.vue -->
<template>
<teleport to="body">
<transition name="modal">
<div v-if="modelValue" class="modal-container">
<div class="modal-content">
<slot />
</div>
</div>
</transition>
</teleport>
</template>
<script>
export default {
props: {
modelValue: Boolean
},
emits: ['update:modelValue']
}
</script>
6.2 样式处理
vue
<style scoped>
.modal-container {
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;
z-index: 1000;
}
.modal-content {
background: white;
padding: 20px;
border-radius: 8px;
max-width: 500px;
width: 100%;
}
</style>
7. 注意事项
- 目标元素必须存在
- SSR注意事项
- 样式作用域问题
- 事件冒泡处理
- 多个Teleport的协调
8. 与其他特性配合
8.1 与Transition结合
vue
<teleport to="body">
<transition name="modal">
<div v-if="show" class="modal">
<!-- 模态框内容 -->
</div>
</transition>
</teleport>
8.2 与Vuex结合
js
// store.js
export const useModalStore = defineStore('modal', {
state: () => ({
activeModals: new Set()
}),
actions: {
showModal(modalId) {
this.activeModals.add(modalId)
},
hideModal(modalId) {
this.activeModals.delete(modalId)
}
}
})