Vue 3 内置组件

Vue 3 提供了一系列内置组件,无需注册即可在任何组件中使用。这些组件覆盖了常见场景如动态组件、过渡动画、内容分发等。下面是对每个内置组件的详细说明和代码示例:

1. <component> - 动态组件

作用 :动态切换不同的组件
核心属性

  • is:指定要渲染的组件(组件名、选项对象或HTML标签)
html 复制代码
<template>
  <component :is="currentComponent"></component>
  <button @click="toggle">切换组件</button>
</template>

<script setup>
import { ref, shallowRef } from 'vue'
import CompA from './CompA.vue'
import CompB from './CompB.vue'

const components = [CompA, CompB]
const currentIndex = ref(0)
const currentComponent = shallowRef(components[0])

function toggle() {
  currentIndex.value = (currentIndex.value + 1) % components.length
  currentComponent.value = components[currentIndex.value]
}
</script>

2. <keep-alive> - 组件缓存

作用 :缓存不活动的组件实例,避免重复渲染
核心属性

  • include:匹配的组件会被缓存(字符串/正则/数组)
  • exclude:匹配的组件不会被缓存
  • max:最大缓存实例数
html 复制代码
<template>
  <keep-alive :include="['CompA']" :max="5">
    <component :is="currentComponent"></component>
  </keep-alive>
</template>

<script setup>
// 被缓存的组件会触发:
//   - activated:激活时
//   - deactivated:停用时
</script>

3. <transition> - 单元素过渡

作用 :为单个元素/组件添加进入/离开过渡
核心属性

  • name:自动生成CSS类名前缀
  • mode:过渡模式(out-in/in-out
  • appear:初始渲染是否应用过渡
html 复制代码
<template>
  <button @click="show = !show">切换</button>
  <transition 
    name="fade"
    mode="out-in"
    @before-enter="onBeforeEnter"
    @after-enter="onAfterEnter">
    <div v-if="show" class="box">内容</div>
  </transition>
</template>

<style>
.fade-enter-active, .fade-leave-active {
  transition: opacity 0.5s, transform 0.5s;
}
.fade-enter-from, .fade-leave-to {
  opacity: 0;
  transform: translateY(20px);
}
</style>

4. <transition-group> - 列表过渡

作用 :为多个元素/组件添加过渡,特别适用于v-for列表
核心特性

  • 默认渲染为<span>,可通过tag指定元素类型
  • 每个元素必须有独立的key
html 复制代码
<template>
  <transition-group name="list" tag="ul">
    <li v-for="item in items" :key="item.id">
      {{ item.text }}
      <button @click="remove(item)">删除</button>
    </li>
  </transition-group>
</template>

<style>
.list-move { /* 移动动画 */
  transition: transform 0.8s ease;
}
.list-enter-active, .list-leave-active {
  transition: all 0.5s;
}
.list-enter-from, .list-leave-to {
  opacity: 0;
  transform: translateX(30px);
}
.list-leave-active {
  position: absolute;
}
</style>

5. <teleport> - 内容传送

作用 :将内容渲染到DOM中的其他位置
核心属性

  • to:目标容器(CSS选择器或DOM元素)
  • disabled:是否禁用传送
html 复制代码
<template>
  <!-- 将模态框传送到body末尾 -->
  <teleport to="body">
    <div v-if="showModal" class="modal">
      <h2>模态框标题</h2>
      <button @click="showModal = false">关闭</button>
    </div>
  </teleport>
</template>

<script setup>
import { ref } from 'vue'
const showModal = ref(false)
</script>

<style>
.modal {
  position: fixed;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  z-index: 9999;
}
</style>

6. <slot> - 内容分发

作用 :在组件中定义内容插槽
核心用法

  • 默认插槽
  • 具名插槽
  • 作用域插槽

父组件

html 复制代码
<ChildComponent>
  <template #header="{ title }">
    <h1>{{ title }}</h1>
  </template>
  
  <template #default>
    <p>主要内容</p>
  </template>
  
  <template #footer>
    <footer>页脚信息</footer>
  </template>
</ChildComponent>

子组件

html 复制代码
<template>
  <div class="container">
    <header>
      <slot name="header" title="页面标题"></slot>
    </header>
    
    <main>
      <slot>默认内容</slot>
    </main>
    
    <footer>
      <slot name="footer"></slot>
    </footer>
  </div>
</template>

7. <suspense> - 异步组件(实验性)

作用 :协调异步依赖的加载状态
核心插槽

  • #default:异步组件内容
  • #fallback:加载中状态
html 复制代码
<template>
  <suspense>
    <template #default>
      <AsyncComponent />
    </template>
    <template #fallback>
      <div class="loading">加载中...</div>
    </template>
  </suspense>
</template>

<script setup>
import { defineAsyncComponent } from 'vue'

const AsyncComponent = defineAsyncComponent(() => 
  import('./AsyncComponent.vue')
)
</script>

使用技巧与最佳实践

  1. 组合使用

    html 复制代码
    <keep-alive>
      <transition name="fade" mode="out-in">
        <component :is="currentView"></component>
      </transition>
    </keep-alive>
  2. 性能优化

    • <keep-alive>使用max属性限制缓存数量
    • 使用shallowRef处理动态组件避免不必要的响应式开销
  3. 动画优化

    css 复制代码
    /* 启用GPU加速 */
    .v-move {
      transition: transform 0.5s;
      will-change: transform;
    }
  4. Teleport 最佳实践

    html 复制代码
    <!-- 动态目标容器 -->
    <teleport :to="isMobile ? '#mobile-container' : '#desktop-container'">
      <!-- 内容 -->
    </teleport>
  5. 插槽进阶用法

    html 复制代码
    <!-- 作用域插槽传值 -->
    <template #item="{ data, index }">
      <div :class="{ active: index === currentIndex }">{{ data.name }}</div>
    </template>

注意事项

  1. <transition-group>需要为每个元素设置唯一key
  2. <teleport>的目标容器必须在组件挂载前存在
  3. <suspense>目前仍是实验性功能,API可能变更
  4. 动态组件的is属性支持组件对象、组件名或HTML标签名
  5. 使用<keep-alive>时,组件会触发activateddeactivated生命周期钩子
相关推荐
HANK1 小时前
Electron + Vue3 桌面应用开发实战指南
前端·vue.js
極光未晚1 小时前
Vue 前端高效分包指南:从 “卡成 PPT” 到 “丝滑如德芙” 的蜕变
前端·vue.js·性能优化
LIUENG2 小时前
Vue2 中的响应式原理
前端·vue.js
梨子同志3 小时前
Vue 3 的 app.use()
vue.js
qb3 小时前
vue3.5.18源码:组件树的递归渲染
前端·vue.js·架构
梨子同志3 小时前
Vue 3 自定义指令
vue.js
夏天想3 小时前
移动端项目框架推荐
前端·javascript·vue.js
zhanle_huang3 小时前
web前端结合Microsoft Office Online 在线预览,vue实现(PPT、Word、Excel、PDF等)
前端·javascript·vue.js
前端小巷子4 小时前
前端虚拟长列表
前端·vue.js·面试