Vue 3 Teleport + Suspense 实战用法

Vue 3 Teleport + Suspense 实战用法

Vue 3 有两个容易被忽略的内置组件:Teleport 和 Suspense。用好了能解决很多实际问题。

Teleport:传送门

解决什么问题

Modal 弹窗有个经典问题:z-index 被父组件的 overflow: hiddentransform 截断。Teleport 直接把 DOM 传送到 <body> 下。

实战:全局 Modal

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- Modal.vue -->
<template>
<Teleport to="body">
<Transition name="modal">
<div v-if="visible" class="modal-overlay" @click.self="close">
<div class="modal-content">
<slot />
</div>
</div>
</Transition>
</Teleport>
</template>

<script setup lang="ts">
defineProps<{ visible: boolean }>()
const emit = defineEmits<{ close: [] }>()

function close() { emit('close') }
</script>

实战:全局通知

1
2
3
4
5
6
7
8
9
10
11
<template>
<Teleport to="body">
<div class="notification-container">
<TransitionGroup name="notif">
<div v-for="n in notifications" :key="n.id" class="notification" :class="n.type">
{{ n.message }}
</div>
</TransitionGroup>
</div>
</Teleport>
</template>

Suspense:异步等待

解决什么问题

组件内有异步操作(如 await 接口)时,传统做法是手动管理 loading 状态。Suspense 自动处理。

基本用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<template>
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<div class="skeleton">加载中...</div>
</template>
</Suspense>
</template>

<script setup lang="ts">
import AsyncComponent from './AsyncComponent.vue'
</script>

实战:异步用户信息

1
2
3
4
5
6
7
8
9
10
11
<!-- UserProfile.vue -->
<template>
<div class="user-profile">
<h2>{{ user.name }}</h2>
<p>{{ user.email }}</p>
</div>
</template>

<script setup lang="ts">
const user = await fetchUser() // 直接 await,Suspense 会自动处理 loading
</script>
1
2
3
4
5
6
7
8
9
10
11
<!-- 父组件 -->
<template>
<Suspense>
<template #default>
<UserProfile :id="userId" />
</template>
<template #fallback>
<UserProfileSkeleton />
</template>
</Suspense>
</template>

组合使用

1
2
3
4
5
6
7
8
9
10
11
12
<template>
<Teleport to="body">
<Suspense>
<template #default>
<Dashboard />
</template>
<template #fallback>
<DashboardSkeleton />
</template>
</Suspense>
</Teleport>
</template>

注意事项

  1. Suspense 还是实验性功能 — 生产环境用要谨慎,未来 API 可能变
  2. Teleport 的 to 必须是 CSS 选择器或 body — 不能传动态值
  3. Teleport 内的组件生命周期不受父组件影响 — 注意副作用清理
  4. Suspense 的 fallback 只显示一次 — 不会重复触发

Vue 3 Teleport + Suspense 实战用法
https://000902.icu/2026/06/24/vue3-teleport-suspense/
作者
Xiazhou
发布于
2026年6月25日
许可协议