Transition
<Transition>
是一个内置组件,它用于在元素或组件的插入、更新和移除时应用过渡效果。Vue 3 的 <Transition>
组件提供了一个声明式的方式来处理这些过渡效果,使开发者能够更容易地添加动画到他们的 Vue 应用中。
基本概念
-
包裹内容:
<Transition>
组件通常包裹一个或多个元素或组件。当这些被包裹的内容的状态(如v-if
或v-show
的值)发生变化时,<Transition>
会自动应用过渡效果。 -
CSS 类名:
<Transition>
组件在元素或组件的不同过渡阶段自动添加或移除特定的 CSS 类名。这使得开发者可以通过 CSS 定义过渡效果,如渐变、滑动、淡入淡出等。 -
过渡模式:
<Transition>
组件支持多种过渡模式,如in-out
(先进入,后离开)和out-in
(先离开,后进入),通过mode
属性来设置。 -
钩子函数:Vue 提供了 JavaScript 钩子函数,允许开发者在过渡的不同阶段执行自定义逻辑,如手动操作 DOM 或执行动画库的方法。
-
列表过渡:除了单个元素或组件的过渡,Vue 3 还支持列表的过渡,通过
<Transition-group>
组件实现。这允许开发者为列表中的每个元素应用过渡效果,同时在列表更新时保持正确的顺序和位置。
使用方法
<template> <button @click="show = !show">Toggle</button> <Transition name="fade"> <div v-if="show">Hello, Vue 3!</div> </Transition>
</template> <script setup lang="ts">
import { ref } from 'vue'; const show = ref(true);
</script> <style scoped>
.fade-enter-active, .fade-leave-active { transition: opacity 0.5s;
}
.fade-enter, .fade-leave-to { opacity: 0;
}
</style>
在上面的例子中,我们定义了一个简单的淡入淡出效果。当 show
的值变化时,<div>
元素会以定义的过渡效果出现或消失。在我们平时实际需求中,可以添加更多的动画效果。
TransitionGroup
基本概念
<TransitionGroup>
是一个内置组件,专门用于处理v-for
列表中的元素或组件的插入、移除和顺序改变时的动画效果。这个组件在构建动态列表,特别是当列表元素可能频繁添加、删除或重新排序时,特别有用。
<TransitionGroup>
组件和<Transition>
组件在功能和用法上有很多相似之处,它们支持和使用基本相同的props、CSS过渡class和JavaScript钩子监听器。然而,它们之间也存在一些关键的差异:
- 容器元素:默认情况下,
<TransitionGroup>
不会渲染一个容器元素。这意味着它不会包裹其内部的元素,而是直接让元素保持在其原始的位置。但你可以通过传入tag
prop来指定一个元素作为容器元素来渲染。 - 过渡模式:在
<TransitionGroup>
中,过渡模式(如in-out
或out-in
)不可用,因为我们不再是在互斥的元素之间进行切换,而是在列表元素之间进行过渡。 - 唯一的key属性:在
<TransitionGroup>
中,列表中的每个元素都必须有一个独一无二的key
attribute。这个key
用于跟踪每个节点的身份,从而可以重用和重新排序现有元素。 - CSS过渡class:与
<Transition>
不同,<TransitionGroup>
的CSS过渡class会被应用在列表内的元素上,而不是容器元素上。这意味着你可以为列表中的每个元素定义不同的过渡效果。
使用<TransitionGroup>
时,你需要将需要过渡的元素放入该组件内部,并使用v-for
指令遍历数据列表。然后,你可以通过定义适当的CSS类来定义过渡效果,如元素的进入、离开和移动时的动画效果。
使用方法
对一个 v-for
列表添加进入 / 离开动画的示例:
<TransitionGroup name="list" tag="ul"><li v-for="item in items" :key="item">{{ item }}</li>
</TransitionGroup>
.list-enter-active,
.list-leave-active {transition: all 0.5s ease;
}
.list-enter-from,
.list-leave-to {opacity: 0;transform: translateX(30px);
}
上面的示例有一些明显的缺陷:当某一项被插入或移除时,它周围的元素会立即发生“跳跃”而不是平稳地移动。我们可以通过添加一些额外的 CSS 规则来解决这个问题:
.list-move, /* 对移动中的元素应用的过渡 */
.list-enter-active,
.list-leave-active {transition: all 0.5s ease;
}.list-enter-from,
.list-leave-to {opacity: 0;transform: translateX(30px);
}/* 确保将离开的元素从布局流中删除以便能够正确地计算移动的动画。 */
.list-leave-active {position: absolute;
}
通过在 JavaScript 钩子中读取元素的 data attribute,我们可以实现带渐进延迟的列表动画。首先,我们把每一个元素的索引渲染为该元素上的一个 data attribute:
<TransitionGrouptag="ul":css="false"@before-enter="onBeforeEnter"@enter="onEnter"@leave="onLeave"
><liv-for="(item, index) in computedList":key="item.msg":data-index="index">{{ item.msg }}</li>
</TransitionGroup>