Vue中的动画特效
1.CSS动画原理
动画进入: 动画如果不给名字,默认:v-enter
原理:在某一时刻给 div 添加 或 删除一些样式
<style> .fade-enter{ opacity:0; } .fade-enter-active{ transition: opacity 1s; //对opacity有一个监控,如果有变化则让opacity在3s中从0变到一个opacity的值。 } } </style> <div id='root'> <transition name='fade'> <!--如果不给name,动画默认名字v-enter --> <div v-show='show'>hello world</div> </transition> </div> <!-- 动画原理说明:当动画开没执行的一瞬间,vue会帮我们在div标签上加fade-enter 和 fade-enter-active 样式, fade-enter-active的执行周期:动画还没开始,准备开始执行第一帧时就存在了,到动画结束时才被移除 当执行到第二帧的时候,fade-enter 被删除,同时 fade-enter-active 中的opacity 检测到变化,就在1s 中变化opacity的值 -->
动画离开:
<style> .fade-leave-to{ opacity:0; } .fade-leave-active{ transition: opacity 3s; } } </style> <div id='root'> <transition name='fade'> <div v-show='show'>hello world</div> </transition> </div> <!-- 动画原理说明:动画开始和结束的瞬间,页面上都有一个fade-leave-active,在动画的运行过程中,要求时刻监听着 div 的opacity这个属性,一旦发生变化,就让他 三秒钟 进行慢慢的过渡。 第一帧的时候,动画把持原有的状态,当进入第二帧时,div 多了一个 fade-leave-to 的属性,fade-leave-active 检测到 opacity 有变化,则在3秒钟 对opacity 进行过渡 -->
案例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="./js/vue.js"></script> <style> .v-enter, .v-leave-to { opacity: 0; } .v-enter-active, .v-leave-active { transition: all 2s; } </style> </head> <body> <div class="app"> <transition> <div v-if='show'>一个有CSS特效的内容</div> </transition> <button @click='btnClick'>切换</button> </div> <script> new Vue({ el: '.app', data: { show: true }, methods: { btnClick: function() { this.show = !this.show; } } }); </script> </body> </html>
2.vue中使用animate.css库
第一步:先在页面中引入animate.css库
第二步:必须自定义动画样式名字(animated)
<!--<transition enter-active-class='animated 动画名称'>--> <transition enter-active-class='animated swing' leave-active-class='animated shake'>
3.使用 appear 让元素第一次显示的时候也有动画(初次动画)
<transition appear <!--声明--> enter-active-class='animated swing' leave-active-class='animated shake' appear-active-class='animated swing' <!--设置第一次显示的时候的动画--> > <div v-show='show'>带有动画效果的文字</div> </transition>
4.同时使用过渡和动画
<transition <!-- type:'transition' --><!--定义以自己写的动画时长为准--> :duration:"{enter:5000,leave:10000}"<!--分别定义动画开始时间用5s,离开时间用10s--> appear <!--声明--> enter-active-class='animated swing v-enter-active' <!--同时使用过渡和动画--> leave-active-class='animated shake v-leave-active'<!--同时使用过渡和动画--> appear-active-class='animated swing' <!--设置第一次显示的时候的动画--> > <!--如果过渡和自己定义的动画时长不一致,特意定义使用谁的时长为准(type:'transition')-->
5.vue中的 JS 动画与 velocity.js
1)vue中也有很多JS动画钩子
<transition name='fade' @before-enter='beforeEnter' <!--元素即将显示时,事件被触发时--> @enter='enterClick' <!--执行动画时,事件被触发--> @after-enter='afterEnter' <!--动画完成时,事件被触发--> > <div v-show='show'>文字内容</div> </transition>
methods:{ beforeEnter:function(el){ // before-enter 有一个参数 el 是div元素 el.style.color='red'; }, enterClick:function(el,done){ //enter 有两个参数,done是回调函数 setTimeout(function(){ el.style.color='green' },2000); setTimeout(function(){ done(); //调用回调函数,才会执行 after 钩子 },4000); }, afterEnter:function(el){ //after里面有一个参数 el.style.color="#000"; } }
2)velocity.js
通过 velocity.js 的简单语法可以实现酷炫的动画效果
methods:{ beforeEnter:function(el){ // 设置opacity=0 el.style.opacity=0; }, enterClick:function(el,done){ Velocity(el,{ //元素名 opacity:1 //设置效果 },{ duration:1000, //设置过渡时间 complete:done // 回调函数,执行after }); }, afterEnter:function(el){ // console.log('动画结束'); } }
6.多个元素或组件过渡
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="./js/vue.js"></script> <style> .v-enter { opacity: 0; } .v-enter-active { transition: all 1s; } </style> </head> <body> <div class="root"> <!-- mode过渡方式 out-in:先隐藏再显示 in-out:先显示再隐藏 --> <transition mode='out-in'> <!-- <child v-if='show'>child</child> <child-one v-else>child-one</child-one> --> <!-- 动态组件过渡 --> <component :is='type'></component> </transition> <button @click='btnClick'>切换</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: { // show: 'true' type: 'child' }, methods: { btnClick: function() { // this.show = !this.show; this.type = (this.type == 'child' ? 'child-one' : 'child'); } } }); </script> </body> </html>
7.Vue中的列表过渡(transition-group)
用法和 transition 一致
<transition-group> <div v-for='item of list' :key='item.id'>{{item.title}}</div> </transition-group> <!--等同于多组加了动画的div--> <transition> <div>Hello World</div> </transition> <transition> <div>Hello World</div> </transition> ...
案例:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> <script src="./js/vue.js"></script> <style> .v-enter, .v-leave-to { opacity: 0; } .v-enter-active, .v-leave-active { transition: all 1s; } </style> </head> <body> <div class="app"> <button @click='btnAdd'>Add</button> <!--动画组--> <transition-group> <!--for循环中 这里的key值不建议使用index,会影响性能--> <div v-for='item of list' :key='item.id'>{{item.title}}</div> </transition-group> </div> <script> var count = 0; var vm = new Vue({ el: '.app', data: { list: [] }, methods: { btnAdd: function() { this.list.push({ id: count++, title: 'Hello World' + count }); } } }); </script> </body> </html>