vue3实现动画
Vue 3 动画实现方法
Vue 3 提供了多种实现动画的方式,包括内置的 Transition 组件、结合 CSS 动画或 JavaScript 钩子,以及第三方动画库。以下是具体实现方法:
使用 Transition 组件
Vue 3 的 Transition 组件可以为元素或组件的进入/离开过渡添加动画效果。通过定义 CSS 类名或 JavaScript 钩子实现动画。
<template>
<button @click="show = !show">Toggle</button>
<Transition name="fade">
<p v-if="show">Hello Vue 3</p>
</Transition>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const show = ref(true)
return { show }
}
}
</script>
<style>
.fade-enter-active, .fade-leave-active {
transition: opacity 0.5s ease;
}
.fade-enter-from, .fade-leave-to {
opacity: 0;
}
</style>
使用 CSS 动画
除了过渡效果,还可以使用 CSS 的 @keyframes 实现更复杂的动画。
<template>
<Transition name="bounce">
<p v-if="show">Bouncing text</p>
</Transition>
</template>
<style>
.bounce-enter-active {
animation: bounce-in 0.5s;
}
.bounce-leave-active {
animation: bounce-in 0.5s reverse;
}
@keyframes bounce-in {
0% { transform: scale(0); }
50% { transform: scale(1.25); }
100% { transform: scale(1); }
}
</style>
使用 JavaScript 钩子
通过 JavaScript 钩子可以实现更精细的动画控制,适合与 GSAP 等动画库结合使用。
<template>
<Transition
@before-enter="beforeEnter"
@enter="enter"
@leave="leave"
:css="false"
>
<p v-if="show">JavaScript animation</p>
</Transition>
</template>
<script>
import { ref } from 'vue'
import gsap from 'gsap'
export default {
setup() {
const show = ref(true)
const beforeEnter = (el) => {
el.style.opacity = 0
el.style.transform = 'translateX(-100px)'
}
const enter = (el, done) => {
gsap.to(el, {
opacity: 1,
x: 0,
duration: 0.5,
onComplete: done
})
}
const leave = (el, done) => {
gsap.to(el, {
opacity: 0,
x: 100,
duration: 0.5,
onComplete: done
})
}
return { show, beforeEnter, enter, leave }
}
}
</script>
列表动画
使用 TransitionGroup 组件可以为 v-for 渲染的列表项添加动画效果。
<template>
<button @click="addItem">Add Item</button>
<button @click="removeItem">Remove Item</button>
<TransitionGroup name="list" tag="ul">
<li v-for="item in items" :key="item">
{{ item }}
</li>
</TransitionGroup>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const items = ref([1, 2, 3, 4, 5])
const addItem = () => {
items.value.push(items.value.length + 1)
}
const removeItem = () => {
items.value.pop()
}
return { items, addItem, removeItem }
}
}
</script>
<style>
.list-enter-active, .list-leave-active {
transition: all 0.5s ease;
}
.list-enter-from, .list-leave-to {
opacity: 0;
transform: translateX(30px);
}
</style>
第三方动画库
可以结合流行的动画库如 Animate.css 或 Motion One 实现丰富的动画效果。
<template>
<Transition
enter-active-class="animate__animated animate__bounceIn"
leave-active-class="animate__animated animate__bounceOut"
>
<p v-if="show">Animate.css animation</p>
</Transition>
</template>
<script>
import { ref } from 'vue'
import 'animate.css'
export default {
setup() {
const show = ref(true)
return { show }
}
}
</script>
动画性能优化
使用 will-change 属性可以提升动画性能,特别是在移动设备上。
.animated-element {
will-change: transform, opacity;
}
避免在动画中使用会触发重排的属性,如 width、height 等,优先使用 transform 和 opacity 实现动画效果。
响应式动画
结合 Vue 的响应式特性,可以根据数据变化动态调整动画参数。
<template>
<div class="box" :style="{ transform: `scale(${scale})` }"></div>
<button @click="scale += 0.1">Scale Up</button>
<button @click="scale -= 0.1">Scale Down</button>
</template>
<script>
import { ref } from 'vue'
export default {
setup() {
const scale = ref(1)
return { scale }
}
}
</script>
<style>
.box {
width: 100px;
height: 100px;
background: #42b983;
transition: transform 0.3s ease;
}
</style>






