引言:
介绍Vue中的css过渡动画
各种情况下的过渡
动画封装
原理
我们可以用transition
标签来包裹我们想要添加css动画的部分
原理:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| <body> <div id="root"> <transition name='fade'> <div v-if="show">你好</div> </transition>
<button @click="handleClick">切换</button> </div>
<script> let vm = new Vue({ el:'#root', data:{ show: true }, methods:{ handleClick(){ this.show=!this.show } } }) </script> </body>
|
当一个元素被transition
标签包裹的时候,Vue会自动的分析css的样式,并且构建一个css流程:
这是出现时的流程
- 在动画即将被执行的一瞬间,会向内部的标签增加两个class:
- fade-enter
- fade-enter-active
1 2 3 4 5 6 7 8
| <style> .fade-enter{ opacity: 0; } .fade-enter-active{ transition: opacity 1s; } </style>
|
这就是一个淡入的效果
- 当运行至第二帧执行时,去掉fade-enter,增添一个fade-enter-to的class
- 执行到结束的时候,会把所有的class全部去掉
都以fade为开头是因为我给transition
起名为fade,默认的名字以v开头即可
这是离开时的流程:
同理
- 填入两个clss
- fade-leave
- fade-leave-active
- 去掉fade-enter,填入fade-enter-to
- 去掉所有的class
1 2 3 4 5 6
| .fade-leave-to{ opacity: 0 } .fade-leave-active{ transition: opacity 1s; }
|
不论v-if,v-show,还是过度组件,都会有过渡动画效果
多元素
1 2 3 4 5 6
| .v-enter, .v-leave-to{ opacity: 0; } .v-enter-active,.v-leave-active{ transition: opacity 1s; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
| <body> <div id="root"> <div> <transition> <div v-if="show" key='hello'>你好</div> <div v-else key='bye'>Bye World</div> </transition> <button @click="handleClick">切换</button> </div> </div>
<script> let vm = new Vue({ el:'#root', data:{ show: true }, methods:{ handleClick(){ this.show=!this.show }, handleBeforeEnter(el){ el.style.opacity = 0; }, handleEnter(el,done){ Velocity(el,{opacity: 1},{duration:1000,complete:done}); }, handleAfterEnter(el){ alert('动画结束') } } }) </script> </body>
|
还可以在transition
上面加mode
属性
mode属性有两个值
- mode=”in-out” 两个元素先进后出
- mode=”out-in” 两个元素先出后进
1 2 3 4
| <transition mode='out-in'> <div v-if="show" key='hello'>你好</div> <div v-else key='bye'>Bye World</div> </transition>
|
多组件
我们需要用到动态组件
其他相同
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title> </title> <script src="./js/vue.js"></script> <link rel="stylesheet" href="js/animate.css"> <script src="js/velocity.js"></script> <style> .v-enter, .v-leave-to{ opacity: 0; } .v-enter-active,.v-leave-active{ transition: opacity 0.5s; } </style> </head> <body> <div id="root"> <transition mode='out-in'> <component :is='type'></component> </transition> <button @click="handleClick">切换</button> </div>
<script> Vue.component("child-one",{ template: '<div>child-one</div> ' }) Vue.component("child-two",{ template: '<div>child-two</div> ' }) let vm = new Vue({ el:'#root', data:{ type:'child-one' }, methods:{ handleClick(){ this.type = this.type === 'child-one'?'child-two':'child-one' } }
}) </script> </body> </html>
|
列表过渡
使用一个新的标签<transition-group>
来实现列表的渲染
1 2 3 4 5 6 7 8
| <div id="root"> <transition-group> <div v-for='item of list' :key='item.id'> {{item.title}} </div> </transition-group> <button @click='handleClick'>Add</button> </div>
|
1 2 3 4 5 6
| .v-enter, .v-leave-to{ opacity: 0; } .v-enter-active,.v-leave-active{ transition: opacity 0.5s; }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| let count = 0;
let vm = new Vue({ el:'#root', data:{ list:[] }, methods:{ handleClick(){ this.list.push({ id:count++, title:'hello' }) } } })
|
封装
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| Vue.component('fade',{ props:['show'], template:'<transition @before-enter="handleBeforeEnter" @enter="handleEnter"><slot v-if="show"></slot></transition>', methods:{ handleBeforeEnter(el){ el.style.color = 'red' }, handleEnter(el,done){ setTimeout(()=>{ el.style.color ='green' },2000) } } })
|
这样封装起来,我们就可以直接使用了
1 2 3
| <fade :show='show'> <div>你好</div> </fade>
|