Vue.js 过渡 & 动画学习笔记

1. 简介

Vue.js 提供了丰富的过渡和动画功能,可以让我们在视图中添加一些动态效果,使页面更加生动有趣。本文将详细介绍 Vue.js 过渡和动画的相关知识,并提供实例演示。

2. 过渡

2.1 CSS 过渡

在 Vue.js 中,可以使用 transition 组件来实现 CSS 过渡效果。transition 组件包裹需要过渡的元素,并通过 name 属性指定过渡效果的名称。

下面是一个简单的实例:

htmlCopy Code
<transition name="fade"> <p v-if="show">Hello, Vue.js!</p> </transition> <button @click="show = !show">{{ show ? '隐藏' : '显示' }}</button>
cssCopy Code
.fade-enter-active, .fade-leave-active { transition: opacity .5s; } .fade-enter, .fade-leave-to { opacity: 0; }

当点击按钮时,v-if 指令将控制 p 元素的显示和隐藏,同时添加了名为 fade 的过渡效果。CSS 样式中,.fade-enter-active.fade-leave-active 表示过渡开始和结束状态的样式,.fade-enter.fade-leave-to 表示过渡过程中的样式变化。

2.2 JS 过渡

Vue.js 还提供了一种 JavaScript 实现的过渡方式,可以通过 transition 组件的 mode 属性来指定。

htmlCopy Code
<transition mode="out-in" @before-enter="beforeEnter" @enter="enter" @leave="leave"> <p :key="text">{{ text }}</p> </transition> <button @click="changeText">更改文本</button>
javascriptCopy Code
data() { return { text: 'Hello, Vue.js!' } }, methods: { beforeEnter(el) { el.style.opacity = 0; }, enter(el, done) { Velocity(el, { opacity: 1 }, { duration: 500, complete: done }); }, leave(el, done) { Velocity(el, { opacity: 0 }, { duration: 500, complete: done }); }, changeText() { this.text = this.text === 'Hello, Vue.js!' ? '你好,Vue.js!' : 'Hello, Vue.js!'; } }

上面代码中,使用 mode 属性指定了 JS 过渡的模式为 out-in,表示新元素先进行过渡,然后删除旧元素。同时设置了 before-enterenterleave 事件,分别对应过渡开始前、过渡中、过渡结束后的回调函数。这里使用了第三方动画库 Velocity.js 来实现动画效果。

3. 动画

除了过渡效果,Vue.js 还提供了丰富的动画效果,包括钩子函数动画、第三方库动画等。

3.1 钩子函数动画

Vue.js 的钩子函数提供了多种动画效果的实现方式,包括基于 CSS、JavaScript 的动画。

htmlCopy Code
<transition @before-enter="beforeEnter" @enter="enter" @leave="leave"> <p v-if="show">Hello, Vue.js!</p> </transition> <button @click="show = !show">{{ show ? '隐藏' : '显示' }}</button>
javascriptCopy Code
methods: { beforeEnter(el) { el.style.transformOrigin = 'left top'; el.style.transform = 'scaleY(0)'; }, enter(el, done) { Velocity(el, { scaleY: 1 }, { duration: 500, complete: done }); }, leave(el, done) { Velocity(el, { scaleY: 0 }, { duration: 500, complete: done }); } }

上面代码中,使用 before-enterenterleave 事件分别对应动画开始前、动画中、动画结束后的回调函数。这里使用了第三方动画库 Velocity.js 来实现动画效果。

3.2 第三方库动画

除了 Vue.js 自带的动画效果和钩子函数动画以外,我们还可以使用第三方库来实现更加复杂的动画效果。

htmlCopy Code
<transition name="bounce"> <p v-if="show">Hello, Vue.js!</p> </transition> <button @click="show = !show">{{ show ? '隐藏' : '显示' }}</button>
cssCopy Code
.bounce-enter-active, .bounce-leave-active { animation: bounce-in .5s; } .bounce-leave-active { animation-name: bounce-out; } @keyframes bounce-in { 0% { opacity: 0; transform: scale(0.3); } 50% { opacity: 1; transform: scale(1.05); } 70% { transform: scale(0.95); } 100% { transform: scale(1); } } @keyframes bounce-out { 0% { transform: scale(1); } 30% { transform: scale(0.95); } 50% { opacity: 1; transform: scale(1.05); } 100% { opacity: 0; transform: scale(0.3); } }

上面代码中,使用 name 属性指定了过渡效果的名称为 bounce,并在 CSS 样式中定义了对应的动画效果,使用了 CSS3 的 animation 属性以及关键帧动画 @keyframes

4. 实例演示

下面是一个多种动画效果的实例演示,包括 CSS 过渡、JS 过渡和第三方库动画。

在线演示

htmlCopy Code
<style> /* CSS 过渡 */ .fade-enter-active, .fade-leave-active { transition: all .5s; } .fade-enter, .fade-leave-to { opacity: 0; transform: translateY(-20px); } /* JS 过渡 */ .bounce-enter-active, .bounce-leave-active { transition: all .5s; } .bounce-enter, .bounce-leave-to { transform: translateX(-50%); } /* 第三方库动画 */ .rotate-enter-active, .rotate-leave-active { animation: rotate .5s; } .rotate-enter, .rotate-leave-to { transform: rotate(360deg); } /* 公共样式 */ * { box-sizing: border-box; } .container { display: flex; justify-content: center; align-items: center; height: 100vh; } .box { display: flex; justify-content: center; align-items: center; width: 200px; height: 200px; margin-right: 20px; border-radius: 4px; font-size: 24px; color: #fff; text-shadow: 1px 1px 2px rgba(0, 0, 0, .6); } .bg1 { background-color: #ff4081; } .bg2 { background-color: #9c27b0; } .bg3 { background-color: #00bcd4; } .bg4 { background-color: #4caf50; } /* 动画名称 */ .fade-enter-active, .fade-leave-active { animation-name: fade; } .bounce-enter-active, .bounce-leave-active { animation-name: bounce; } @keyframes rotate { 0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); } } @keyframes fade { 0% { opacity: 0; transform: translateY(-20px); } 100% { opacity: 1; transform: translateY(0); } } @keyframes bounce { 0%, 50%, 100% { transform: translateX(-50%); } 40%, 60% { transform: translateX(0); } } </style> <div id="app"> <div class="container"> <transition name="fade"> <div v-if="show1" class="box bg1">{{ text }}</div> </transition> <transition mode="out-in" @before-enter="beforeEnter" @enter="enter" @leave="leave"> <div :key="text" class="box bg2">{{ text }}</div> </transition> <transition name="rotate"> <div v-show="show3" class="box bg3">{{ text }}</div> </transition> <div class="box bg4">{{ text }}</div> </div> <button @click="changeText">更改文本</button> </div> <script src="https://cdn.jsdelivr.net/npm/vue"></script> <script src="https://cdn.jsdelivr.net/npm/velocity-animate"></script> <script> new Vue({ el: '#app', data: { text: 'Hello, Vue.js!', show1: true, show3: true }, methods: { beforeEnter(el) { el.style.transform = 'translateX(-100%)'; }, enter(el, done) { Velocity(el, { translateX: 0 }, { duration: 500, complete: done }); }, leave(el, done) { Velocity(el, { translateX: '100%' }, { duration: 500, complete: done }); }, changeText() { this.text = this.text === 'Hello, Vue.js!' ? '你好,Vue.js!' : 'Hello, Vue.js!'; this.show1 = !this.show1; this.show3 = !this.show3; } } }); </script>

上面代码中,演示了 CSS 过渡、JS 过渡和第三方库动画三种动画方式的实现,并提供了实时更改文本内容的按钮,让用户可以更好地感受动画效果。