在现代Web应用中,动画效果是提升用户体验的重要手段。Vue作为一个渐进式框架,提供了丰富的动画API,让开发者能够轻松实现各种过渡效果
Vue动画的基础是CSS过渡和动画,通过在元素插入、更新或移除时添加/移除CSS类来触发动画效果。Vue提供了特殊的组件和指令来简化这个过程。
核心CSS类名:
.v-enter-from
:进入动画的起始状态.v-enter-active
:进入动画的持续状态.v-enter-to
:进入动画的结束状态.v-leave-from
:离开动画的起始状态.v-leave-active
:离开动画的持续状态.v-leave-to
:离开动画的结束状态除了CSS动画,Vue还允许通过JavaScript钩子函数控制动画,这在需要更复杂的动画逻辑时非常有用。
核心钩子函数:
beforeEnter
enter
afterEnter
enterCancelled
beforeLeave
leave
afterLeave
leaveCancelled
Vue2通过
组件实现单元素/组件的过渡效果:
<template>
<div>
<button @click="show = !show">Togglebutton>
<transition name="fade">
<p v-if="show">Hello Worldp>
transition>
div>
template>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter-from, .fade-leave-to {
opacity: 0;
}
style>
对于多个元素的过渡,Vue2提供了
组件:
<template>
<div>
<button @click="addItem">Add Itembutton>
<transition-group name="slide" tag="ul">
<li v-for="item in items" :key="item.id">{{ item.text }}li>
transition-group>
div>
template>
<style>
.slide-enter-active {
transition: all 0.3s ease-out;
}
.slide-leave-active {
transition: all 0.3s cubic-bezier(1, 0.5, 0.8, 1);
position: absolute;
}
.slide-enter-from, .slide-leave-to {
transform: translateX(10px);
opacity: 0;
}
style>
Vue2中可以通过JavaScript钩子完全控制动画:
<template>
<transition
@before-enter="beforeEnter"
@enter="enter"
@leave="leave"
:css="false"
>
<div v-if="show" class="box">div>
transition>
template>
<script>
export default {
data() {
return {
show: false
}
},
methods: {
beforeEnter(el) {
el.style.opacity = 0;
el.style.transform = 'scale(0.9)';
},
enter(el, done) {
Velocity(el, { opacity: 1, transform: 'scale(1)' }, {
duration: 300,
complete: done
});
},
leave(el, done) {
Velocity(el, { opacity: 0, transform: 'scale(0.9)' }, {
duration: 300,
complete: done
});
}
}
}
script>
Vue3通过组合式API提供了更灵活的动画控制方式:
<template>
<div>
<button @click="show = !show">Togglebutton>
<transition name="fade">
<div v-if="show" class="box">div>
transition>
div>
template>
<script setup>
import { ref } from 'vue';
const show = ref(false);
script>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.5s ease;
}
.fade-enter-from, .fade-leave-to {
opacity: 0;
}
style>
useTransition
组合式函数Vue3提供了useTransition
组合式函数,用于更精细地控制动画:
<template>
<div>
<button @click="toggle">Togglebutton>
<div v-if="isVisible" v-bind="transitionStyles">
Animated Content
div>
div>
template>
<script setup>
import { ref, computed, useTransition, withSpring } from 'vue';
const isVisible = ref(true);
const { style: transitionStyles, enter, leave } = useTransition({
duration: 500,
mode: 'in-out'
});
const toggle = async () => {
if (isVisible.value) {
await leave();
isVisible.value = false;
} else {
isVisible.value = true;
await enter();
}
};
script>
Vue3中的列表过渡更加流畅,支持更复杂的动画效果:
<template>
<div>
<button @click="addItem">Add Itembutton>
<transition-group name="item" tag="ul">
<li v-for="item in items" :key="item.id" :style="itemStyle">
{{ item.text }}
li>
transition-group>
div>
template>
<script setup>
import { ref, reactive } from 'vue';
const items = ref([
{ id: 1, text: 'Item 1' },
{ id: 2, text: 'Item 2' }
]);
const addItem = () => {
items.value.push({
id: Date.now(),
text: `Item ${items.value.length + 1}`
});
};
const itemStyle = {
transition: 'all 0.5s ease',
overflow: 'hidden'
};
script>
<style>
.item-enter-from {
opacity: 0;
transform: translateY(30px);
}
.item-leave-to {
opacity: 0;
transform: translateY(-30px);
height: 0;
margin: 0;
}
style>
特性 | Vue2 | Vue3 |
---|---|---|
单元素过渡 | 组件 |
保留,支持组合式API |
列表过渡 | 组件 |
保留,动画性能优化 |
JavaScript钩子 | 组件属性 | 支持组合式API,更灵活 |
动态过渡 | 有限支持 | 全面支持,通过useTransition |
Vue3的动画系统在性能上有显著提升:
Vue3的组合式API为动画带来了更高的灵活性:
利用Vue的响应式系统创建基于状态的复杂动画:
<template>
<div>
<input v-model.number="scale" type="range" min="0.5" max="2" step="0.1">
<transition name="scale">
<div class="box" :style="{ transform: `scale(${scale})` }">
Scalable Box
div>
transition>
div>
template>
<script setup>
import { ref } from 'vue';
const scale = ref(1);
script>
<style>
.scale-enter-active, .scale-leave-active {
transition: transform 0.5s ease;
}
.scale-enter-from {
transform: scale(0);
}
.scale-leave-to {
transform: scale(0);
}
style>
在Vue Router中实现页面间的过渡效果:
<template>
<div id="app">
<router-view v-slot="{ Component }">
<transition name="fade" mode="out-in">
<component :is="Component" />
transition>
router-view>
div>
template>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.5s;
}
.fade-enter-from, .fade-leave-to {
opacity: 0;
}
style>
结合GSAP等专业动画库实现复杂动画:
<template>
<div>
<button @click="animate">Animatebutton>
<div ref="box" class="box">div>
div>
template>
<script setup>
import { ref, onMounted } from 'vue';
import gsap from 'gsap';
const box = ref(null);
const animate = () => {
gsap.to(box.value, {
duration: 1,
x: 100,
rotation: 360,
scale: 1.5,
ease: 'elastic.out(1, 0.3)',
onComplete: () => {
gsap.to(box.value, {
duration: 0.5,
x: 0,
rotation: 0,
scale: 1,
ease: 'power2.out'
});
}
});
};
script>
transform
和opacity
in-out
或out-in
模式避免元素重叠Vue的动画系统为开发者提供了强大而灵活的工具,无论是简单的过渡效果还是复杂的交互动画,都能轻松实现。Vue3在继承Vue2动画系统的基础上,通过组合式API和性能优化,进一步提升了动画的开发体验和运行效率。
在实际开发中,建议根据项目需求选择合适的动画方式:
组件