Vue 中的动画特效
CSS 实现标签显隐
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Vue中CSS动画原理</title> <script src="./vue.js"></script> </head> <body> <div id="root"> <div v-if="show"> hello world </div> <button @click="handleClick">切换</button> </div> <script> var vm = new Vue({ el: "#root", data: { show: true, }, methods: { handleClick: function () { this.show = !this.show } } }) </script> </body> </html>
transition 过渡动画
如果要在vue中实现过渡动画,需要使用 transition 标签,名字可以随便取。
显示动画原理
代码案例 - 3s完成显示
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Vue中CSS动画原理</title> <script src="./vue.js"></script> <style> .fade-enter { opacity: 0; } .fade-enter-active { transition: opacity 3s; } </style> </head> <body> <div id="root"> <!-- 如果要实现过渡动画,需要使用 transition 标签,名字可以随便取,需要与css样式对应 --> <transition name="fade"> <div v-if="show"> hello world </div> </transition> <button @click="handleClick">切换</button> </div> <script> var vm = new Vue({ el: "#root", data: { show: true, }, methods: { handleClick: function () { this.show = !this.show } } }) </script> </body> </html>
隐藏动画原理
案例代码 - 隐藏
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Vue中CSS动画原理</title> <script src="./vue.js"></script> <style> .fade-enter { opacity: 0; } .fade-enter-active { transition: opacity 3s; } .fade-leave-to{ opacity: 0; } .fade-leave-active{ transition: opacity 3s; } </style> </head> <body> <div id="root"> <!-- 如果要实现过渡动画,需要使用 transition 标签,名字可以随便取,需要与css样式对应 --> <transition name="fade"> <div v-if="show"> hello world </div> </transition> <button @click="handleClick">切换</button> </div> <script> var vm = new Vue({ el: "#root", data: { show: true, }, methods: { handleClick: function () { this.show = !this.show } } }) </script> </body> </html>
代码优化
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Vue中CSS动画原理</title> <script src="./vue.js"></script> <style> .fade-enter, .fade-leave-to { opacity: 0; } .fade-enter-active, .fade-leave-active { transition: opacity 3s; } </style> </head> <body> <div id="root"> <!-- 如果要实现过渡动画,需要使用 transition 标签,名字可以随便取,需要与css样式对应 --> <transition name="fade"> <div v-if="show"> hello world </div> </transition> <button @click="handleClick">切换</button> </div> <script> var vm = new Vue({ el: "#root", data: { show: true, }, methods: { handleClick: function () { this.show = !this.show } } }) </script> </body> </html>
在Vue中使用Animate.css库
学前-代码案例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>在vue中使用Animate.css库</title> <script src="./vue.js"></script> <style> @keyframes bounce-in{ 0%{ transform: scale(0); } 50%{ transform: scale(1.5); } 100%{ transform: scale(1); } } .fade-enter-active{ transform-origin: left center; animation: bounce-in 1s; } .fade-leave-active { transform-origin: left center; /* 动画反向运行 */ animation: bounce-in 1s reverse; } </style> </head> <body> <div id="root"> <!-- 如果要实现过渡动画,需要使用 transition 标签,名字可以随便取,需要与css样式对应 --> <transition name="fade"> <div v-if="show"> hello world </div> </transition> <button @click="handleClick">切换</button> </div> <script> var vm = new Vue({ el: "#root", data: { show: true, }, methods: { handleClick: function () { this.show = !this.show } } }) </script> </body> </html>
在显隐过程中有放大缩小效果。
自定义动画名称
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>在vue中使用Animate.css库</title> <script src="./vue.js"></script> <style> @keyframes bounce-in { 0% { transform: scale(0); } 50% { transform: scale(1.5); } 100% { transform: scale(1); } } /* 自定义动画效果名称 */ .active { transform-origin: left center; animation: bounce-in 1s; } .leave { transform-origin: left center; /* 动画反向运行 */ animation: bounce-in 1s reverse; } </style> </head> <body> <div id="root"> <!-- 如果要实现过渡动画,需要使用 transition 标签,名字可以随便取,需要与css样式对应 --> <!-- 自定义动画名称需要声明 --> <transition name="fade" enter-active-class="active" leave-active-class="leave"> <div v-if="show"> hello world </div> </transition> <button @click="handleClick">切换</button> </div> <script> var vm = new Vue({ el: "#root", data: { show: true, }, methods: { handleClick: function () { this.show = !this.show } } }) </script> </body> </html>
Animate.css 官网
https://daneden.github.io/animate.css/
代码案例
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>在vue中使用Animate.css库</title> <script src="./vue.js"></script> <!-- 引入css文件 --> <link rel="stylesheet" href="./animate.css"> </head> <body> <div id="root"> <!-- 如果要实现过渡动画,需要使用 transition 标签,名字可以随便取,需要与css样式对应 --> <!-- 自定义动画名称需要声明 --> <transition name="fade" enter-active-class="animated swing" leave-active-class="animated shake"> <div v-if="show"> hello world </div> </transition> <button @click="handleClick">切换</button> </div> <script> var vm = new Vue({ el: "#root", data: { show: true, }, methods: { handleClick: function () { this.show = !this.show } } }) </script> </body> </html>
进入退出都会添加动画效果!
animate 使用注意事项
- 要使用自定义形式使用 animate.css。
- class类里面必须包含一个 animated 具体的类,根据需求不同,把动画效果写在后面。
在Vue中同时使用过渡和动画
appear 在刷新界面的时候也有动画
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>在Vue中同时使用过渡和动画</title> <script src="./vue.js"></script> <link rel="stylesheet" href="./animate.css"> </head> <body> <div id="root"> <!-- 如果要实现过渡动画,需要使用 transition 标签,名字可以随便取,需要与css样式对应 --> <!-- 自定义动画名称需要声明 --> <transition name="fade" appear enter-active-class="animated swing" leave-active-class="animated shake" appear-active-class="animated swing"> <div v-if="show"> hello world </div> </transition> <button @click="handleClick">切换</button> </div> <script> var vm = new Vue({ el: "#root", data: { show: true, }, methods: { handleClick: function () { this.show = !this.show } } }) </script> </body> </html>
vue实现既有动画又有过渡效果,设置动画时长
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>在Vue中同时使用过渡和动画</title> <script src="./vue.js"></script> <link rel="stylesheet" href="./animate.css"> <style> .fade-leave-to, .fade-enter { opacity: 0; } .fade-leave-active, .fade-enter-active { transition: opacity 3s; } </style> </head> <body> <div id="root"> <!-- 如果要实现过渡动画,需要使用 transition 标签,名字可以随便取,需要与css样式对应 --> <!-- 自定义动画名称需要声明 --> <!-- type="transition" 动画时长以 transition 为准 --> <!-- :duration="10000" 自己定义动画时长 --> <transition :duration="{enter:5000,leave:10000}" name="fade" appear enter-active-class="animated swing fade-enter-active" leave-active-class="animated shake fade-leave-active" appear-active-class="animated swing"> <div v-if="show"> hello world </div> </transition> <button @click="handleClick">切换</button> </div> <script> var vm = new Vue({ el: "#root", data: { show: true, }, methods: { handleClick: function () { this.show = !this.show } } }) </script> </body> </html>
Vue中的JS动画
@before-enter 方法
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Vue中的JS动画与Velocity.js</title> <script src="./vue.js"></script> </head> <body> <div id="root"> <transition name="fade" @before-enter="handleBeferEnter"> <div v-if="show"> hello world </div> </transition> <button @click="handleClick">切换</button> </div> <script> var vm = new Vue({ el: "#root", data: { show: true, }, methods: { handleClick: function () { this.show = !this.show }, handleBeferEnter:function(){ console.log("aaa") }, } }) </script> </body> </html>
使用js将动画标签设置为红色
handleBeferEnter:function(el){ // el参数指动画包裹的div标签 // 将动画标签设置为红色 el.style.color="red" },
整体代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Vue中的JS动画与Velocity.js</title> <script src="./vue.js"></script> </head> <body> <div id="root"> <transition name="fade" @before-enter="handleBeferEnter"> <div v-if="show"> hello world </div> </transition> <button @click="handleClick">切换</button> </div> <script> var vm = new Vue({ el: "#root", data: { show: true, }, methods: { handleClick: function () { this.show = !this.show }, handleBeferEnter:function(el){ // el参数指动画包裹的div标签 // 将动画标签设置为红色 el.style.color="red" }, } }) </script> </body> </html>
@enter 方法
enter 使动画两秒钟后颜色变为绿色
handleEnter: function (el, dane) { // el参数指动画包裹的div标签 // dane 是一个回调函数 setTimeout(() => { // 两秒之后颜色变绿 el.style.color = "green" }, 2000) },
整体代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Vue中的JS动画与Velocity.js</title> <script src="./vue.js"></script> </head> <body> <div id="root"> <transition name="fade" @before-enter="handleBeferEnter" @enter="handleEnter"> <div v-if="show"> hello world </div> </transition> <button @click="handleClick">切换</button> </div> <script> var vm = new Vue({ el: "#root", data: { show: true, }, methods: { handleClick: function () { this.show = !this.show }, handleBeferEnter: function (el) { // el参数指动画包裹的div标签 // console.log("aaa") el.style.color = "red" }, handleEnter: function (el, dane) { // el参数指动画包裹的div标签 // dane 是一个回调函数 setTimeout(() => { // 两秒之后颜色变绿 el.style.color = "green" }, 2000) }, } }) </script> </body> </html>
结束之后手动调用一下done,标识动画执行完成了,done 被调用完之后,会触发一个事件,叫 @after-enter
handleEnter: function (el, done) { // el参数指动画包裹的div标签 // done 是一个回调函数 setTimeout(() => { // 两秒之后颜色变绿 el.style.color = "green" // 结束之后手动调用一下done,标识动画执行完成了 // done 被调用完之后,会触发一个事件,叫 @after-enter done }, 2000)
@after-enter 方法
handleAfterEnter:function(el){ // 动画结束之后字体颜色重新变为黑色 el.style.color='#000' },
整体代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Vue中的JS动画与Velocity.js</title> <script src="./vue.js"></script> </head> <body> <div id="root"> <transition name="fade" @before-enter="handleBeferEnter" @enter="handleEnter" @after-enter="handleAfterEnter"> <div v-if="show"> hello world </div> </transition> <button @click="handleClick">切换</button> </div> <script> var vm = new Vue({ el: "#root", data: { show: true, }, methods: { handleClick: function () { this.show = !this.show }, handleBeferEnter: function (el) { // el参数指动画包裹的div标签 // console.log("aaa") el.style.color = "red" }, handleEnter: function (el, done) { // el参数指动画包裹的div标签 // done 是一个回调函数 setTimeout(() => { // 两秒之后颜色变绿 el.style.color = "green" }, 2000) // 四秒之后结束动画 setTimeout(()=>{ // 结束之后手动调用一下done,标识动画执行完成了 done() },4000) }, handleAfterEnter:function(el){ // 动画结束之后字体颜色重新变为黑色 el.style.color='#000' }, } }) </script> </body> </html>
出场动画对应的为:@befer-leave | @leave | @after-leave
使用方法和上边提到的 enter 入场动画的使用方法相同,在此就不在累述。
js常用的动画库 - Velocity.js
案例代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Vue中的JS动画与Velocity.js</title> <script src="./vue.js"></script> <!-- 引入js动画库 --> <script src="./velocity.js"></script> </head> <body> <div id="root"> <transition name="fade" @before-enter="handleBeferEnter" @enter="handleEnter" @after-enter="handleAfterEnter"> <div v-if="show"> hello world </div> </transition> <button @click="handleClick">切换</button> </div> <script> var vm = new Vue({ el: "#root", data: { show: true, }, methods: { handleClick: function () { this.show = !this.show }, handleBeferEnter: function (el) { el.style.opacity = 0; }, handleEnter: function (el, done) { // 使用Velocity实现动画。 // 第一个参数指 添加动画的对象 el标签。 // 第二个参数指 动画效果,这里是设置透明度为1. // 第三个参数指 动画的时间,这里设置的1s。 Velocity(el, { opacity: 1 }, { duration: 1000, // 表示Velocity对应的动画执行完成之后,complete对应的函数done回调函数自动执行,意思为动画执行完成 complete:done }) }, handleAfterEnter: function (el) { console.log('动画结束!') }, } }) </script> </body> </html>
Vue中的多个元素或组件的过渡
多个元素的过渡动画
实现点击按钮两个标签来回切换
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Vue中多个元素或组件的过渡-元素</title> <script src="./vue.js"></script> <!-- 引入js动画库 --> <script src="./velocity.js"></script> </head> <body> <div id="root"> <!-- 如果要实现过渡动画,需要使用 transition 标签,名字可以随便取,需要与css样式对应 --> <transition name="fade"> <div v-if="show">Hello World </div> <div v-else >Bye World</div> </transition> <button @click="handleClick">toggle</button> </div> <script> var vm = new Vue({ el: "#root", data: { show: true, }, methods: { handleClick: function () { this.show = !this.show } } }) </script> </body> </html>
多个元素加入渐隐渐现动画
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Vue中多个元素或组件的过渡-元素</title> <script src="./vue.js"></script> <!-- 引入js动画库 --> <!-- <script src="./velocity.js"></script> --> <style> .v-enter,.v-leave-to{ opacity: 0; } .v-enter-active,.v-leave-active{ transition: opacity 1s; } </style> </head> <body> <div id="root"> <!-- 如果要实现过渡动画,需要使用 transition 标签,名字可以随便取,需要与css样式对应 --> <transition> <!-- key值防止dom复用,导致动画失效 --> <div v-if="show" key="hello">Hello World </div> <div v-else key="bye">Bye World</div> </transition> <button @click="handleClick">toggle</button> </div> <script> var vm = new Vue({ el: "#root", data: { show: true, }, methods: { handleClick: function () { this.show = !this.show } } }) </script> </body> </html>
<!-- mode="in-out" 使得元素先进入在隐藏 也可以写 “out-in”先隐藏在进入 --> <transition mode="in-out"> <!-- key值防止dom复用,导致动画失效 --> <div v-if="show" key="hello">Hello World </div> <div v-else key="bye">Bye World</div> </transition>
需要进入的元素进入完成在隐藏该消失的元素。
实现组件间的动画效果
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Vue中多个元素或组件的过渡-组件</title> <script src="./vue.js"></script> <!-- 引入js动画库 --> <!-- <script src="./velocity.js"></script> --> <style> .v-enter, .v-leave-to { opacity: 0; } .v-enter-active, .v-leave-active { transition: opacity 1s; } </style> </head> <body> <div id="root"> <transition mode="in-out"> <!-- 动态组件 --> <component :is="type"></component> </transition> <button @click="handleClick">toggle</button> </div> <script> Vue.component('child', { template: '<div>child</div>' }) Vue.component('child-one', { template: '<div>child-one</div>' }) var vm = new Vue({ el: "#root", data: { type: 'child', }, methods: { handleClick: function () { this.type = this.type === 'child' ? 'child-one' : 'child' } } }) </script> </body> </html>
Vue中的列表过渡
transition-group 标签实现列表动画
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>VUE中的列表过渡</title> <script src="./vue.js"></script> <style> .v-enter,.v-leave-to{ opacity: 0; } .v-enter-active,.v-leave-active{ transition: opacity 1s; } </style> </head> <body> <div id="root"> <!-- transition-group 用于列表的动画 --> <transition-group> <div v-for="item of list" :key="item.id"> {{item.title}} </div> </transition-group> <button @click="handleBtnClick">Add</button> </div> <script> var count = 0; var vm = new Vue({ el: "#root", data: { list: [] }, methods: { handleBtnClick: function () { this.list.push({ id: count++, title: 'hello world' }) }, } }) </script> </body> </html>
Vue中的动画封装
案例1 动画封装
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Vue中动画的封装</title> <script src="./vue.js"></script> <style> .fade-enter,.fade-leave-to { opacity: 0; } .fade-enter-active,.fade-leave-active { transition: opacity 1s; } </style> </head> <body> <div id="root"> <fade :show="show"> <div v-if="show"> hello Vue </div> </fade> <button @click="handleClick">切换</button> </div> <script> Vue.component('fade',{ props:['show'], template:` <transition name="fade"> <slot v-if="show"></slot> </transition> ` }) var vm = new Vue({ el: "#root", data: { show: true, }, methods: { handleClick: function () { this.show = !this.show } } }) </script> </body> </html>
案例2 封装动画的使用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Vue中动画的封装</title> <script src="./vue.js"></script> <style> .fade-enter, .fade-leave-to { opacity: 0; } .fade-enter-active, .fade-leave-active { transition: opacity 1s; } </style> </head> <body> <div id="root"> <fade :show="show"> <div v-if="show"> hello Vue </div> </fade> <fade :show="show"> <h2 v-if="show"> hello javascript </h2> </fade> <button @click="handleClick">切换</button> </div> <script> Vue.component('fade', { props: ['show'], template: ` <transition name="fade"> <slot v-if="show"></slot> </transition> ` }) var vm = new Vue({ el: "#root", data: { show: true, }, methods: { handleClick: function () { this.show = !this.show } } }) </script> </body> </html>
案例3 封装CSS动画
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <meta http-equiv="X-UA-Compatible" content="ie=edge"> <title>Vue中动画的封装</title> <script src="./vue.js"></script> </head> <body> <div id="root"> <fade :show="show"> <div v-if="show"> hello Vue </div> </fade> <fade :show="show"> <h2 v-if="show"> hello javascript </h2> </fade> <button @click="handleClick">切换</button> </div> <script> Vue.component('fade', { props: ['show'], template: ` <transition name="fade" @before-enter="handleBeforeEnter" @enter="handleEnter"> <slot v-if="show"></slot> </transition> `, methods:{ handleBeforeEnter:function(el){ el.style.color = 'red' }, handleEnter:function(el,done){ setTimeout(()=>{ el.style.color = 'green' done() },2000) } } }) var vm = new Vue({ el: "#root", data: { show: true, }, methods: { handleClick: function () { this.show = !this.show } } }) </script> </body> </html>
Vue 官网
更多知识点进Vue官网:https://cn.vuejs.org/
Vue官方文档:https://cn.vuejs.org/v2/guide/
进入/离开 & 列表过渡:https://cn.vuejs.org/v2/guide/transitions.html