Vue.js 提供了几个内置的特殊组件,它们可以解决超越基本组件功能之外的特定 UI 需求。本文档涵盖了三个核心特殊组件:Teleport、KeepAlive 和 Suspense。这些组件分别负责控制 DOM 放置、组件缓存和异步渲染。
有关过渡和动画的信息,请参阅 过渡。
Vue.js 中的特殊组件是内置组件,它们提供的高级功能与数据渲染不直接相关,而是专注于控制组件行为和 DOM 结构。与常规组件不同,它们每个都有独特的内部标志(例如 __isTeleport、__isKeepAlive 和 __isSuspense),渲染器会识别并特殊处理它们。
来源
Teleport 允许您将组件内容渲染到 DOM 中的任何位置,无论组件在虚拟 DOM 层级中的哪个位置挂载。这对于模态框、工具提示和其他应在正常文档流之外渲染的覆盖元素特别有用。
当 disabled 为 true 时,Teleport 会在原始位置渲染内容。当 defer 为 true 时,Teleport 会等到初始渲染后才将内容移动到目标位置,这对于可能在初始渲染期间不存在的目标很有用。
来源
Teleport 在原始位置(占位符注释保留在此处)和目标位置(内容在此处渲染)之间维护一个虚拟连接。
来源
挂载:
更新:
to prop 更改,内容将被移动到新目标disabled 更改为 true,内容将移回原始位置disabled 更改为 false,内容将移到目标位置SSR 支持:
来源
KeepAlive 会缓存不活跃的组件实例,而不是销毁它们。这可以在组件切换之间保留组件状态,避免昂贵的重新渲染,并跨组件停用/重新激活周期维护滚动位置或用户输入。
include 和 exclude prop 根据组件名称控制应缓存哪些组件。max prop 限制了可以同时缓存的组件实例数量(使用 LRU 驱逐)。
来源
KeepAlive 添加了两个额外的生命周期钩子
onActivated:当缓存的组件插入 DOM 时调用onDeactivated:当组件从 DOM 中移除但保留在缓存中时调用来源
缓存机制:
Map 按键缓存 VNodesSet 按 LRU 顺序跟踪键停用流程:
激活过程:
来源
Suspense 提供了一种在组件中处理异步依赖关系的方法,在所有异步操作完成之前显示回退内容。对于具有异步 setup 函数的组件或嵌套的异步组件,这尤其有用。
Suspense 提供两个插槽
default:包含具有潜在异步依赖关系的主组件fallback:在等待异步操作时显示的后备内容来源
来源
挂载阶段:
解析阶段:
suspensible: true 冒泡到父 Suspense 组件更新处理:
来源
特殊组件可以组合起来创建强大的 UI 模式。以下是一些常见的组合
使用 Teleport 和 KeepAlive 时,请记住 KeepAlive 必须是它应缓存的组件的父组件,而不是 Teleport 的父组件
<!-- Correct: KeepAlive wraps component -->
<Teleport to="#modal">
<KeepAlive>
<MyComponent v-if="show" />
</KeepAlive>
</Teleport>
<!-- Incorrect: KeepAlive wraps Teleport -->
<KeepAlive>
<Teleport to="#modal">
<MyComponent v-if="show" />
</Teleport>
</KeepAlive>
Suspense 与异步组件配合使用效果尤佳,在组件加载完成之前显示加载状态
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<LoadingSpinner />
</template>
</Suspense>
在服务器端渲染 (SSR) 期间,特殊组件具有特定的同构化行为
来源
每个特殊组件都有不同的性能特征
| 组件 | 优点 | 成本 | 最佳实践 |
|---|---|---|---|
| Teleport | 更清晰的 DOM 结构,保持上下文 | 对 DOM 操作有轻微的开销 | 用于需要特定定位的 UI 元素 |
| KeepAlive | 避免昂贵的重新渲染,保留状态 | 缓存组件的内存使用 | 使用 max 限制缓存大小,使用 include/exclude |
| Suspense | 为异步组件提供更好的用户体验 | 增加了组件树的复杂性 | 对于简单的加载状态,请考虑其他选项 |
来源