详情

首页手游攻略 一文完整指南Vue3内置组件的使用

一文完整指南Vue3内置组件的使用

佚名 2026-08-21 13:00:02

平时做技术实践时,很多问题不是概念不会,而是细节没串起来。拿“一文详细解析Vue3内置组件的采用”来说,它看着像小点,放到项目里常会牵出环境、配置、兼容性和维护成本。下面按实际采用顺序,把思路、关键写法和容易踩坑的地方讲清楚,便于大家直接对照操作。

目录
  • 前言:
  • 1.<Transition>
  • 2.<TransitionGroup>
  • 3.<keepAlive>
    • 基本采用
    • 包含/排除
    • 最大缓存实例数
    • 缓存实例的生命周期
      • 注意事项
  • 4.<Teleport>
    • 基本采用
      • 禁用 Teleport
      • 结语:

        前言:

        在这个场景下,vue3作为当前主流的前端框架之一,其内置组件体系为开发者提供了高效、灵活的解决方案。这些组件不仅简化了常用功能的开发流程,还借助组合式API和性能优化进一步提升开发体验。

        实际处理时,建议借助官方文档拿到最准确的信息,避免第三方解读带来的偏差。官方资源通常包含最新更新和完整细节,确保学习内容的权威性。官网地址:vue3内置组件

        1.<Transition>

        实际处理时,熟悉css动画的就能够看出这跟过渡动画有关,官网也说明了它能够为单个元素或组件提供动画过渡的效果。它能够将进入和离开动画应用到借助默认插槽传递给它的元素或组件上进入或离开能够由以下的条件之一触发:

        • 由v-if触发
        • 由v-show触发
        • 由特殊元素<component>切换的动态组件
        • 改变特殊的key属性

        <template>
          <p class="app">
            <button @click="show = !show">点击</button>
            <transition>
              <p v-if="show">hello</p>
            </transition>
          </p>
        </template>

        <script setup>
        import { ref } from 'vue';

        const show = ref(true)
        </script>

        <style scoped>
        .v-enter-active,
        .v-leave-active {
          transition:opacity 0.5s ease;
        }
        .v-enter-from,
        .v-leave-to {
          opacity: 0;
        }
        </style>

        结合项目来看,这就是官网上面的一个例子,点击按钮文字隐藏,但它不是直接隐藏的,而是opacity的值从1到0经过了0.5s,所以用户看到的是文字慢慢的在消失,样式中.v-enter-active等是什么意思呢?官网这边给了一张图就很好理解了。

        Enter表示进入,Leave表示离开。

        落到代码里,v-enter-from表示进入动画的起始状态,配合上面的例子就很好理解了,开始起始状态的透明度为0,到进入动画的结束状态也就是v-enter-to的透明度变为1,这个过程就是v-enter-active,所以我们需在这个过程中设置动画时间以及过渡的速度,就比如上面设置的ease表示从快到慢过渡。理解了进入,离开也就同理了。

        结合项目来看,但了解这个还远远不够,也无法应对项目中的所有场景,当我们的项目中需多个transition内置组件同时它们的动画效果不同时,因此需给每个transition组件定义一个名字,好将它们区分开来,避免样式混淆,只需在transition内置组件上添加一个name属性,给它一个名称,代码如下所示:

            <transition name="fade">
              <p v-if="show">hello</p>
            </transition>

        结合项目来看,进入动画与结束动画的类名也要进行修改,只需将v替换成我们设置的过渡效果名:

        .fade-enter-active,
        .fade-leave-active {
          transition: opacity 0.5s ease;
        }

        .fade-enter-from,
        .fade-leave-to {
          opacity: 0;
        }

        2.<TransitionGroup>

        实际处理时,用来对 v-for 列表中的元素或组件的插入、移除和顺序改变添加动画效果。

        在这个场景下,<TransitionGroup>内置组件和<Transition>内置组件一样都是添加动画效果,拥有相同的props和特定的CSS class选择器以及相同的JavaScript钩子函数,它们的区别如下所示:

        • 结合项目来看,默认情况下,它不会渲染一个容器元素。但你能够借助传入 tag prop来指定一个元素作为容器元素来渲染。
        • 过渡模式在这里不可用,因为我们不再实在互斥的元素之间进行切换。
        • 列表中的每个元素都必须有一个独一无二的 key attribute。
        • CSS 过渡 class 会被应用在列表内的元素上,而不是容器元素上。
        • 实际处理时,<TransitionGroup>用作与列表,<Transition>用作于单个元素。

        示例:

        <template>
          <p class="app">
            <button @click="addItem">Add</button>
            <transition-group name="list" tag="ul">
              <li v-for="item in items" :key="item.id">
                {{ item.value }}
                <button @click="deleteItem(item.id)">Delete</button>
              </li>
            </transition-group>
          </p>
        </template>

        <script setup>
        import { ref } from 'vue';

        const items = ref([
          { id: 1, value: 1 },
          { id: 2, value: 2 },
          { id: 3, value: 3 }
        ]);

        // 添加
        function addItem() {
          items.value.unshift({
            id: Date.now(),
            value: Math.floor(Math.random() * 11)
          });
        }

        // 删除
        function deleteItem(id) {
          items.value = items.value.filter(item => item.id !== id);
        }

        </script>

        落到代码里,tag='ul'时,会将其渲染为ul标签,所以能够在其添加li标签列表。

        添加动画样式

        .list-move,
        .list-enter-active,
        .list-leave-active {
          transition: all 1s ease;
        }

        .list-enter-from,
        .list-leave-to {
          opacity: 0;
          transform: translateX(30px);
        }

        从实现思路看,我们往数据前面添加数据时,下面的数据会有一个像“让位置”的操作,但这个动作有点僵硬,所以能够采用.v-move给其添加动画效果。

        从实现思路看,但是当我们删除数据时,下面的数据会在上面的数据删除后立马向上去“占位置”,当我们也希望这样有一个过渡的动画效果时,就需在.list-leave-active中添加position: absolute;,就是需在离开的过程中,让其脱离文档流,这样做的原因是便于浏览器正确的计算移动的动画。

        .list-leave-active{
          position: absolute;
        }

        3.<keepAlive>

        它的功能是在多个组件间动态切换时缓存被移除的组件实例.

        理解这一步时,<keepAlive>包裹动态组件时,会缓存不活跃的组件实例,而不是去销毁它们。

        理解这一步时,任何时候都只能有一个活跃组件实例作为<keepAlive>的直接子节点。

        落到代码里,一个组件在<keepAlive>中被切换时,它的activated和deactivated生命周期钩子将被调用,这两个生命周期是<keepAlive>特有的,用来替代mounted和unmounted。这适用来<keepAlive>的直接子节点及其所有子孙节点。

        基本采用

        <template>
          <p class="app">
            <label><input type="radio" v-model="componentId" :value="home">home</label>
            <label><input type="radio" v-model="componentId" :value="User">User</label>
            <component :is="componentId"></component>
          </p>
        </template>

        <script setup>
        import { shallowRef } from 'vue';
        import home from './components/home.vue';
        import User from './components/User.vue';

        const componentId = shallowRef(home);
        </script>

        当我点击复选框时,会进行组件的切换

        home:

        User:

        在这个场景下,当我们在home组件中点击按钮会增加数据的值,但切换到User组件再切回到home组件中时,组件会被从新渲染,所以原本添加的值会回到初始值,但有些场景下我们不需组件从新渲染,希望将其缓存起来,就能够采用到<keepAlive>了,方法很轻松,只需用<keepAlive>包裹需切换的组件即可。

        <template>
          <p class="app">
            <label><input type="radio" v-model="componentId" :value="home">home</label>
            <label><input type="radio" v-model="componentId" :value="User">User</label>
            <keep-alive>
              <component :is="componentId"></component>
            </keep-alive>
          </p>
        </template>

        现在,在组件切换时状态也能被保留了。

        包含/排除

        在这个场景下,因为<keepAlive>默认会缓存内部的所有组件实例,可能有些情况下我们不需包含的所有组件实例都被缓存,能够借助 包含(include)排除(exclude)落到代码里,prop来定制该行为。这两个prop的值都能够是一个以是一个以英文逗号分隔的字符串、一个正则表达式,或是包含这两种类型的一个数组:

            <keep-alive include="home">
              <component :is="componentId"></component>
            </keep-alive>

        这样它就只会缓存home组件。

        在这个场景下,在 Vue3.2.34 或以上的版本里,采用 <script setup> 的单文件组件会自动根据文件名生成对应的 name 选项,无需再手动声明。

        最大缓存实例数

        能够借助传入 max prop来限制可被缓存的最大组件实例数。

        实际处理时,若缓存的实例数量即将超过指定的那个最大数量,则最久没有被访问的缓存实例将被销毁,以便为新的实例腾出空间。

            <keep-alive :max="10">
              <component :is="componentId"></component>
            </keep-alive>

        缓存实例的生命周期

        从实现思路看,在 Vue.js 的<keep-alive>组件中,被缓存的组件实例会经历特定的生命周期钩子,这些钩子与普通组件的生命周期有所不同。以下是缓存实例的完整生命周期:

        activated:

        从实现思路看,当缓存组件被激活(从缓存中重新插入到 DOM 中)时触发。适合在此钩子中执行需恢复的操作,比如重新加载数据或启动定时器。

        deactivated:

        在这个场景下,当缓存组件被销毁(从 DOM 中移除同时存入缓存)时触发。适合在此钩子中执行清理操作,比如清除定时器或取消未完成的请求。

        home.vue:

        <template>
            <p class="home">
                <button @click="num++">Add</button>
                <p>{{ num }}</p>
            </p>
        </template>

        <script setup>
        import { ref, onActivated, onDeactivated } from 'vue'
        const num = ref(0)

        onActivated(() => {
          console.log('组件被激活');
        });

        onDeactivated(() => {
          console.log('组件被销毁');
        });
        </script>

        注意事项

        • 实际处理时,缓存组件的 created 和 mounted 钩子仅在首次加载时触发,后续激活时不会重复触发。
        • 从实现思路看,若组件被缓存后再次激活,只会触发 activated 钩子,而不会触发 mounted。
        • 在这个场景下,缓存实例数量超过 max 限制时,最久未被访问的实例会被销毁,其 destroyed 钩子会被触发
        • 从实现思路看,这两个钩子不仅适用来<keep-alive>缓存的根组件,也适用来缓存树中的后代组件。

        4.<Teleport>

        落到代码里,Teleport 是 Vue.js 3 中引入的一个内置组件,允许将子节点渲染到 DOM 树中的其他位置,而不受父组件层级结构的限制。这在处理模态框、通知、弹出菜单等需脱离当前 DOM 结构的场景时很有用。

        基本采用

        理解这一步时,Teleport 组件借助 to 属性指定目标容器,目标容器能够是 DOM 选择器字符串或实际的 DOM 元素。

        App.vue:

        <template>
          <p class="app">
            <button @click="showMsg = true">Click me</button>
            <p>
              <MessageBox msg="Hello World" v-model:showMsg="showMsg"/>
            </p>
          </p>
        </template>

        <script setup>
        import { ref } from 'vue'
        import MessageBox from './components/MessageBox.vue';
        const showMsg = ref(false);
        </script>

        MessageBox.vue:

        <template>
            <p class="message" v-if="showMsg">
                <p class="message_box">
                    <p class="message_box_text">{{ msg }}</p>
                    <p class="message_box_button">
                        <el-button type="primary" @click="handleClick">确定</el-button>
                    </p>
                </p>
            </p>
        </template>

        <script setup>

        const { msg, showMsg } = defineProps({
            msg: String,
            showMsg: Boolean
        })

        const emit = defineEmits(['update:showMsg'])
        function handleClick() {
            emit('update:showMsg', false)
        }
        </script>

        <style scoped lang="less">
        .message {
            position: fixed;
            top: 0;
            left: 0;
            width: 100vw;
            height: 100vh;
            background-color: rgba(0, 0, 0, .4);

            .message_box {
                padding: 0 10px;
                width: 300px;
                height: 150px;
                position: absolute;
                top: 50%;
                left: 50%;
                transform: translate(-50%, -50%);
                background-color: #fff;
                border-radius: 20px;
                display: flex;
                flex-direction: column;
                overflow: hidden;

                .message_box_text {
                    flex: 0 0 80px;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                }

                .message_box_button {
                    flex: 1;
                    display: flex;
                    align-items: center;
                    justify-content: center;
                }
            }
        }
        </style>

        实际处理时,这边我写了个很轻松的示例,点击按钮会出现一个模态框,点击模态框中的确定按钮会隐藏模态框,这里面就涉及到了组件通信,如果有不懂的能够看看我之前的文章关于组件通信的——Vue3组件通信

        打开控制台能够看到模态框的位置

        在这个场景下,在 Vue 3 里,<Teleport>件可用来将模板中的内容渲染到 DOM 的其他位置,而不受父组件层级的限制。

        示例:将弹窗内容移至 body 元素下

        <template>
            <teleport to='body'>
                <p class="message" v-if="showMsg">
                    <p class="message_box">
                        <p class="message_box_text">{{ msg }}</p>
                        <p class="message_box_button">
                            <el-button type="primary" @click="handleClick">确定</el-button>
                        </p>
                    </p>
                </p>
            </teleport>
        </template>

        关键点说明

        • 理解这一步时,to 属性指定目标容器,能够是 CSS 选择器(如#app、.container)或 DOM 元素(如 body)。
        • 在这个场景下,被<teleport> 包裹的内容仍保持 Vue 的响应式特性,事件和逻辑不受影响。
        • 适合处理模态框、通知提示等需脱离当前组件层级的场景。

        注意事项

        • 确保目标容器在 DOM 中已存在,否则内容无法正确挂载。
        • 动态修改 to 属性可实现内容在不同容器间切换。

        禁用 Teleport

        理解这一步时,在某些场景里,可能需根据特定条件禁用 Teleport 功能。比如,针对不同设备或布局需求,动态控制组件的位置。

        从实现思路看,我们能够借助对<Teleport>态地传入一个 disabled prop 来处理这两种不同情况。

        <template>
            <teleport to='body' :disabled="showMsg">
                <p class="message" v-if="showMsg">
                    <p class="message_box">
                        <p class="message_box_text">{{ msg }}</p>
                        <p class="message_box_button">
                            <el-button type="primary" @click="handleClick">确定</el-button>
                        </p>
                    </p>
                </p>
            </teleport>
        </template>

        结语:

        在这个场景下,在vue3中其实还有一个内置组件<Suspense>,为什么在这里没有介绍呢?那是因为作为内置组件未被详细说明,主要原因是其当前仍处于实验性阶段。官方明确声明该功能尚未稳定,未来API可能发生变更,故不建议在生产环境中依赖这一特性。

        在这个场景下,随着 Vue 生态的不断发展,掌握这些核心组件将有助于开发更灵活、高效的前端应用。建议结合官方文档和实际项目实践,深入理解其采用场景和最佳实践。

        到此这篇关于Vue3内置组件的采用的文章就介绍到这了,更多相关Vue3内置组件内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多兼容脚本之家!

        您可能感兴趣的文章:

        • Vue3内置组件Teleport采用方法详解
        • Vue3中内置组件Teleport的基本采用与典型案例
        • vue3的内置组件汇总

        相关资讯
        点击查看更多
        游戏推荐
        推荐专题
        热门阅读
        推荐下载