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生命周期钩子
相关推荐
古夕16 小时前
第三方 SSO 接入实践:redirect_uri 编码、回调一致性与跨项目联调
前端·vue.js
Ruihong16 小时前
Vue withDefaults 转 React:VuReact 怎么处理?
vue.js·react.js·面试
稀土熊猫君18 小时前
一个人能做出什么开源项目?
vue.js·后端·开源
DarkLONGLOVE2 天前
快速上手 Pinia!Vue3 极简状态管理使用教程
javascript·vue.js
宸翰2 天前
解决 uni-app App 端 vue-i18n 占位符丢失:封装跨端可用的 tf 格式化方法
前端·vue.js·uni-app
用户2136610035722 天前
VueRouter进阶-动态路由与嵌套路由
前端·vue.js
暴走的小呆3 天前
Vue 2 中 Object 的变化侦测:从 getter/setter 到 Dep、Watcher、Observer
vue.js
英勇无比的消炎药3 天前
TinyVue v-auto-tip: 文本超长自动提示的优雅方案
vue.js
时光足迹3 天前
腾讯云 TRTC UniApp SDK 从入门到上线
前端·vue.js·uni-app
时光足迹3 天前
uni-app 里把加密视频嵌入页面播放?我分析了 4 种方案,只有 1 种接近完美
前端·vue.js·uni-app