Vue 内置组件全解析:提升开发效率的五大神器

作者:90后晨仔日期:2025/10/19

在 Vue 开发中,除了我们日常编写的业务组件外,框架还提供了一系列内置组件,它们为我们处理常见的开发场景提供了优雅的解决方案。今天,我们就来深入探讨 Vue 的五大内置组件:TransitionTransitionGroupKeepAliveTeleportSuspense

1. Transition - 丝滑的过渡动画

什么是 Transition?

Transition 组件用于在元素或组件的插入、更新和移除时添加动画效果,让用户体验更加流畅。

基本使用

1<template>
2  <button @click="show = !show">切换</button>
3  
4  <Transition name="fade">
5    <p v-if="show">Hello, Vue!</p>
6  </Transition>
7</template>
8
9<script setup>
10import { ref } from 'vue'
11
12const show = ref(true)
13</script>
14
15<style scoped>
16.fade-enter-active,
17.fade-leave-active {
18  transition: opacity 0.5s ease;
19}
20
21.fade-enter-from,
22.fade-leave-to {
23  opacity: 0;
24}
25</style>
26

过渡类名详解

Transition 组件会自动应用以下 6 个 CSS 类名:

  • v-enter-from:进入动画的起始状态
  • v-enter-active:进入动画的激活状态
  • v-enter-to:进入动画的结束状态
  • v-leave-from:离开动画的起始状态
  • v-leave-active:离开动画的激活状态
  • v-leave-to:离开动画的结束状态

注意:其中的 v 是默认前缀,可以通过 name 属性自定义。

JavaScript 钩子

除了 CSS 过渡,还可以使用 JavaScript 钩子:

1<template>
2  <Transition
3    @before-enter="onBeforeEnter"
4    @enter="onEnter"
5    @after-enter="onAfterEnter"
6    @enter-cancelled="onEnterCancelled"
7    @before-leave="onBeforeLeave"
8    @leave="onLeave"
9    @after-leave="onAfterLeave"
10    @leave-cancelled="onLeaveCancelled"
11  >
12    <div v-if="show">内容</div>
13  </Transition>
14</template>
15
16<script setup>
17import { ref } from 'vue'
18
19const show = ref(true)
20
21const onBeforeEnter = (el) => {
22  // 元素插入 DOM 前的回调
23}
24
25const onEnter = (el, done) => {
26  // 元素插入 DOM 后的回调
27  // 需要手动调用 done() 来结束过渡
28  done()
29}
30</script>
31

模式控制

1<Transition mode="out-in">
2  <button :key="isEditing" @click="isEditing = !isEditing">
3    {{ isEditing ? '保存' : '编辑' }}
4  </button>
5</Transition>
6

支持的模式:

  • in-out:新元素先进入,当前元素后离开
  • out-in:当前元素先离开,新元素后进入

2. TransitionGroup - 列表过渡专家

什么是 TransitionGroup?

TransitionGroup 组件专门用于处理动态列表中元素的进入、离开和移动的动画效果。

基本使用

1<template>
2  <button @click="addItem">添加</button>
3  <button @click="removeItem">移除</button>
4  
5  <TransitionGroup name="list" tag="ul">
6    <li v-for="item in items" :key="item.id">
7      {{ item.text }}
8    </li>
9  </TransitionGroup>
10</template>
11
12<script setup>
13import { ref } from 'vue'
14
15const items = ref([
16  { id: 1, text: '项目 1' },
17  { id: 2, text: '项目 2' },
18  { id: 3, text: '项目 3' }
19])
20
21let nextId = 4
22
23const addItem = () => {
24  items.value.push({ id: nextId++, text: `项目 ${nextId}` })
25}
26
27const removeItem = () => {
28  items.value.pop()
29}
30</script>
31
32<style scoped>
33.list-enter-active,
34.list-leave-active {
35  transition: all 0.5s ease;
36}
37.list-enter-from {
38  opacity: 0;
39  transform: translateX(30px);
40}
41.list-leave-to {
42  opacity: 0;
43  transform: translateX(-30px);
44}
45/* 确保离开的元素脱离文档流 */
46.list-leave-active {
47  position: absolute;
48}
49</style>
50

关键特性

  1. 必须设置 key:每个元素都需要唯一的 key
  2. 支持 CSS 变换:自动检测元素位置变化应用移动动画
  3. tag 属性:指定包裹容器的标签,默认为不渲染包裹元素

3. KeepAlive - 组件缓存大师

什么是 KeepAlive?

KeepAlive 组件用于缓存不活动的组件实例,避免重复渲染,保持组件状态。

基本使用

1<template>
2  <div>
3    <button @click="currentTab = 'Home'">首页</button>
4    <button @click="currentTab = 'About'">关于</button>
5    
6    <KeepAlive>
7      <component :is="currentTab" />
8    </KeepAlive>
9  </div>
10</template>
11
12<script setup>
13import { ref, shallowRef } from 'vue'
14import Home from './Home.vue'
15import About from './About.vue'
16
17const currentTab = ref('Home')
18const tabs = {
19  Home,
20  About
21}
22</script>
23

高级配置

1<KeepAlive 
2  :include="/Home|About/" 
3  :exclude="['Settings']" 
4  :max="10"
5>
6  <component :is="currentComponent" />
7</KeepAlive>
8
  • include:只有名称匹配的组件会被缓存(字符串、正则或数组)
  • exclude:任何名称匹配的组件都不会被缓存
  • max:最多可缓存的组件实例数量

生命周期钩子

被缓存的组件会获得两个新的生命周期钩子:

1<script setup>
2import { onActivated, onDeactivated } from 'vue'
3
4onActivated(() => {
5  // 组件被激活时调用
6  console.log('组件激活')
7})
8
9onDeactivated(() => {
10  // 组件被停用时调用
11  console.log('组件停用')
12})
13</script>
14

4. Teleport - 任意门组件

什么是 Teleport?

Teleport 组件允许我们将组件模板的一部分"传送"到 DOM 中的其他位置,而不影响组件的逻辑关系。

基本使用

1<template>
2  <div class="app">
3    <button @click="showModal = true">打开模态框</button>
4    
5    <Teleport to="body">
6      <div v-if="showModal" class="modal">
7        <div class="modal-content">
8          <h2>模态框标题</h2>
9          <p>这是模态框内容</p>
10          <button @click="showModal = false">关闭</button>
11        </div>
12      </div>
13    </Teleport>
14  </div>
15</template>
16
17<script setup>
18import { ref } from 'vue'
19
20const showModal = ref(false)
21</script>
22
23<style scoped>
24.modal {
25  position: fixed;
26  top: 0;
27  left: 0;
28  right: 0;
29  bottom: 0;
30  background: rgba(0, 0, 0, 0.5);
31  display: flex;
32  justify-content: center;
33  align-items: center;
34}
35
36.modal-content {
37  background: white;
38  padding: 20px;
39  border-radius: 8px;
40}
41</style>
42

多个 Teleport 到同一目标

1<template>
2  <Teleport to="#modals">
3    <div>第一个模态框</div>
4  </Teleport>
5  
6  <Teleport to="#modals">
7    <div>第二个模态框</div>
8  </Teleport>
9</template>
10

渲染结果:

1<div id="modals">
2  <div>第一个模态框</div>
3  <div>第二个模态框</div>
4</div>
5

禁用 Teleport

1<Teleport to="body" :disabled="isMobile">
2  <div>内容</div>
3</Teleport>
4

5. Suspense - 异步组件管家

什么是 Suspense?

Suspense 组件用于协调组件树中的异步依赖,在等待异步组件时显示加载状态。

基本使用

1<template>
2  <Suspense>
3    <template #default>
4      <AsyncComponent />
5    </template>
6    
7    <template #fallback>
8      <div class="loading">加载中...</div>
9    </template>
10  </Suspense>
11</template>
12
13<script setup>
14import { defineAsyncComponent } from 'vue'
15
16const AsyncComponent = defineAsyncComponent(() => 
17  import('./AsyncComponent.vue')
18)
19</script>
20
21<style scoped>
22.loading {
23  text-align: center;
24  padding: 20px;
25  color: #666;
26}
27</style>
28

异步 setup 组件

1<template>
2  <Suspense>
3    <template #default>
4      <ComponentWithAsyncSetup />
5    </template>
6    
7    <template #fallback>
8      <div>加载用户数据...</div>
9    </template>
10  </Suspense>
11</template>
12
13<script setup>
14import { ref } from 'vue'
15
16const ComponentWithAsyncSetup = {
17  async setup() {
18    const userData = await fetchUserData()
19    return { userData }
20  },
21  template: [`<div>用户: {{ userData.name }}</div>`](https://xplanc.org/primers/document/zh/03.HTML/EX.HTML%20%E5%85%83%E7%B4%A0/EX.div.md)
22}
23
24async function fetchUserData() {
25  // 模拟 API 调用
26  return new Promise(resolve => {
27    setTimeout(() => {
28      resolve({ name: 'Vue 开发者' })
29    }, 2000)
30  })
31}
32</script>
33

事件处理

1<template>
2  <Suspense @pending="onPending" @resolve="onResolve" @fallback="onFallback">
3    <AsyncComponent />
4  </Suspense>
5</template>
6
7<script setup>
8const onPending = () => {
9  console.log('开始加载异步组件')
10}
11
12const onResolve = () => {
13  console.log('异步组件加载完成')
14}
15
16const onFallback = () => {
17  console.log('显示加载状态')
18}
19</script>
20

实战案例:组合使用内置组件

让我们看一个综合使用多个内置组件的例子:

1<template>
2  <div class="app">
3    <!-- 标签页切换 -->
4    <nav>
5      <button 
6        v-for="tab in tabs" 
7        :key="tab.id"
8        @click="currentTab = tab.id"
9      >
10        {{ tab.name }}
11      </button>
12    </nav>
13    
14    <!-- 主要内容区域 -->
15    <main>
16      <KeepAlive>
17        <Transition name="slide" mode="out-in">
18          <Suspense>
19            <template #default>
20              <component :is="currentTabComponent" />
21            </template>
22            <template #fallback>
23              <div class="loading">加载中...</div>
24            </template>
25          </Suspense>
26        </Transition>
27      </KeepAlive>
28    </main>
29    
30    <!-- 全局通知 -->
31    <Teleport to="#notifications">
32      <TransitionGroup name="notification">
33        <div 
34          v-for="notification in notifications" 
35          :key="notification.id"
36          class="notification"
37        >
38          {{ notification.message }}
39        </div>
40      </TransitionGroup>
41    </Teleport>
42  </div>
43</template>
44
45<script setup>
46import { ref, computed, defineAsyncComponent } from 'vue'
47
48// 标签页状态
49const currentTab = ref('home')
50const tabs = [
51  { id: 'home', name: '首页' },
52  { id: 'profile', name: '个人资料' },
53  { id: 'settings', name: '设置' }
54]
55
56// 异步组件
57const currentTabComponent = computed(() => 
58  defineAsyncComponent(() => import(`./${currentTab.value}.vue`))
59)
60
61// 通知系统
62const notifications = ref([])
63
64// 添加通知
65const addNotification = (message) => {
66  const id = Date.now()
67  notifications.value.push({ id, message })
68  setTimeout(() => {
69    notifications.value = notifications.value.filter(n => n.id !== id)
70  }, 3000)
71}
72</script>
73
74<style scoped>
75.slide-enter-active,
76.slide-leave-active {
77  transition: all 0.3s ease;
78}
79
80.slide-enter-from {
81  opacity: 0;
82  transform: translateX(50px);
83}
84
85.slide-leave-to {
86  opacity: 0;
87  transform: translateX(-50px);
88}
89
90.notification-enter-active,
91.notification-leave-active {
92  transition: all 0.3s ease;
93}
94
95.notification-enter-from {
96  opacity: 0;
97  transform: translateY(-30px);
98}
99
100.notification-leave-to {
101  opacity: 0;
102  transform: translateX(100%);
103}
104
105.loading {
106  text-align: center;
107  padding: 50px;
108  font-size: 18px;
109}
110</style>
111

总结

Vue 的内置组件为我们提供了强大的工具来处理常见的开发需求:

  • Transition:为单个元素/组件添加过渡动画
  • TransitionGroup:为列表项添加排序和动画效果
  • KeepAlive:缓存组件状态,提升性能
  • Teleport:将内容渲染到 DOM 任意位置
  • Suspense:优雅处理异步组件加载状态

这些内置组件不仅功能强大,而且可以灵活组合使用,帮助我们构建更加优雅、高效的 Vue 应用。掌握它们的使用,将让你的 Vue 开发技能更上一层楼!

希望这篇文章能帮助你全面理解 Vue 的内置组件,并在实际项目中灵活运用。Happy Coding! 🚀


Vue 内置组件全解析:提升开发效率的五大神器》 是转载文章,点击查看原文


相关推荐


Java Kubernetes本地部署RuoYi框架jar包
自由的疯2025/10/18

在本地 Kubernetes 集群中部署 RuoYi 框架的 JAR 包是一个很好的实践,可以帮助你更好地理解和掌握 Kubernetes 的应用部署流程。以下是详细的步骤,指导你在本地 Kubernetes 集群中部署 RuoYi 框架的 JAR 包。 1. 准备环境 1.1 安装 Minikube 或 kind 首先,确保你已经安装了 Minikube 或 kind 来本地运行 Kubernetes 集群。这里以 Minikube 为例进行说明。 安装 kubectl: curl -LO


从 Tomcat 与 Jetty 的对比,聊聊影响一个服务并发能力的关键因素
G探险者2025/10/16

大家好,我是G探险者! 在 Java 服务体系中,Tomcat 与 Jetty 是最常见的 Web 容器。很多人认为,只要加大连接数或线程数,就能提升并发能力。 但事实远比想象复杂:连接数只是冰山一角,背后还有线程模型、I/O 模型、内核资源限制等多重因素。 本文从 Tomcat 与 Jetty 的对比 入手,系统讲清楚——到底是什么在决定你的服务并发上限。 🧩 一、Tomcat 与 Jetty 的架构差异 1️⃣ Tomcat 的工作模型 Tomcat 默认采用 多线程 + 阻塞 I/O


面试真实经历某商银行大厂Java问题和答案总结(三)
360_go_php2025/10/15

​ 1. 深拷贝和浅拷贝 ​编辑 问:什么是深拷贝和浅拷贝?它们之间有什么区别? 浅拷贝(Shallow Copy): 浅拷贝指的是复制对象的引用,而不是复制对象本身。也就是说,对于对象中的引用类型字段,浅拷贝只是复制了这些字段的引用,而没有复制字段引用的对象本身。 如果原始对象和拷贝对象中有相同的引用类型字段,修改其中一个字段会影响到另一个对象。​编辑 深拷贝(Deep Copy): 深拷贝指的是复制对象本身,并且递归地复制对象中的所有引用类型字段,确保两个对象中的引用类型字段互不影响。


Swift 基础语法全景(一):从变量到类型安全
unravel20252025/10/14

常量与变量:let vs var 声明语法 // 常量:一次赋值,终身不变 let maximumLoginAttempts = 10 // 最大尝试次数,业务上不允许修改 // 变量:可反复写入 var currentAttempt = 0 // 当前尝试次数,失败+1 延迟赋值 只要「第一次读取前」完成初始化即可,不必一行写完。 var randomGenerator = SystemRandomNumberGenerator() let


Linux挂载NTFS分区指南
依赖倒不置2025/10/12

在使用Windows和Linux双系统的电脑上,通常我们可能也需要在Linux上访问NTFS分区。虽然Linux用户一般来说不一定会有分区的习惯,但是在双系统情况下,两个系统复用NTFS分区也是很常见的。 今天,就来讨论双系统复用分区的场景下,如何正确地在Linux挂载NTFS分区。 1,Linux的NTFS驱动 事实上,老版本的Linux内核并不原生支持读取NTFS分区,尤其是NTFS是Windows系统专有的文件系统,而不是开放的。因此很长一段时间,都是使用ntfs-3g这个开源驱动实现在L


老题新解|十进制转二进制
程序员莫小特2025/10/10

《信息学奥赛一本通》第160题:十进制转二进制 题目描述 给定一个十进制整数 n n n,请将其转换为对应的二进制表示,并输出。 输入格式 输入包含一行,一个整数 n


单机已达上限?PerfTest 分布式压测登场,轻松模拟百万用户洪峰
Go有引力2025/10/9

前言 在前一篇文章中,我们详细介绍了 perftest 的单机压测能力,展示了它如何通过极简的命令行实现对 HTTP/1.1、HTTP/2、HTTP/3 与 WebSocket 的高性能测试。然而,当业务系统庞大、服务部署分布式、网络链路复杂时,单机的压测能力显然无法满足真实生产环境的模拟需求。 幸运的是,perftest 不止于单机。它同样支持 分布式集群压测,通过 Collector + Agent 的架构,让你轻松在多台机器上同时发起测试,实现百万乃至千万级并发的性能评估。 为什么选择分


Webpack实战笔记:从自动构建到本地服务器搭建的完整流程
XiangCoder2025/10/7

作为前端开发者,Webpack 是绕不开的构建工具。最近系统学习了 Webpack 的自动构建和服务器搭建,整理了一套从基础到实战的操作笔记,包含具体案例和踩坑经验,适合新手跟着实操。 前言:为什么需要 Webpack 构建工具? 刚开始写前端项目时,我们习惯在 index.html 里手动引入各种 js、css 文件。但随着项目变大,会遇到两个核心问题: 资源越来越多,手动管理引入路径容易出错(尤其是加哈希值优化缓存时); 开发时需要频繁刷新页面看效果,效率太低。 Web


Android系统模块编译调试与Ninja使用指南
龙之叶2025/10/6

模块编译调试方法 (此处举例framework、installd、SystemUI等模块的编译调试,其他类似) 1. Framework模块编译 Android系统代码的framework目录内,一共有3个模块单独编译:framework、services、framework-res.apk。 注意:偶尔会有改了代码但没检测到,编译结束后产物并未更新的情况,所以可以考虑先剪切掉原先的产物或者检查产物更新时间确保已经重新编译。 步骤: 完成根目录下 source build/envsetup.sh


精选 4 款开源免费、美观实用的 MAUI UI 组件库,助力轻松构建美观且功能丰富的应用程序!
追逐时光者2025/10/5

前言 一套优秀的 UI 组件库不仅能大幅提升开发效率,还能显著增强应用的视觉体验与交互质感。今天大姚给大家分享 4 款开源免费、美观实用的 MAUI UI 组件库,助你轻松打造专业级的跨平台应用程序。 .NET MAUI介绍 .NET 多平台应用 UI (.NET MAUI) 是一个跨平台框架,用于使用 C# 和 XAML 创建本机移动和桌面应用。使用 .NET MAUI,可从单个共享代码库开发可在 Android、iOS、macOS 和 Windows 上运行的应用。 .NET开源免费的跨平

首页编辑器站点地图

Copyright © 2025 聚合阅读

License: CC BY-SA 4.0