Vue中CSS动画原理的实现
下面这段代码,是点击按钮实现hello world显示与隐藏
<div id="root"> <div v-if="show">hello world</div> <button @click="handleclick">按钮</button> </div> let vm = new vue({ el: '#root', data: { show:true }, methods: { handleclick(){ this.show = !this.show } } })
此时有一个需求,希望是在显示与隐藏时,能实现渐隐渐现的动画效果。
<div id="root"> <transition name="fade"> <div v-if="show">hello world</div> </transition> <button @click="handleclick">按钮</button> </div> let vm = new vue({ el: '#root', data: { show:true }, methods: { handleclick(){ this.show = !this.show } } })
如果希望hello world有一个动画效果的话,需要在外面套一层transition标签,意思它包裹的内容,有一个动画效果,可以给它一个名字name="fade"。
enter
当一个元素被transition标签包裹之后,vue 会自动的分析元素的css样式,然后构建动画流程
在动画还没有执行的一瞬间,vue 会帮我们在dom标签上添加两个class,分别是fade-enter、fade-enter-active。
当动画第一帧执行结束之后,transition这个标签分析过,里面有一个动画效果,vue 会在动画运行到第二帧的时候,会将dom标签上v-enter的class删除,再添加一个v-enter-to的class。
接着动画会继续执行,执行到结束的一瞬间,vue 会干一件事,它会把之前添加的v-enter-to和v-enter-active都删除,
.fade-enter{ opacity: 0; } .fade-enter-active{ transition: opacity 3s; } <div id="root"> <transition name="fade"> <div v-if="show">hello world</div> </transition> <button @click="handleclick">按钮</button> </div> let vm = new vue({ el: '#root', data: { show:true }, methods: { handleclick(){ this.show = !this.show } } })
我们只需要在css中给fade-enter和fade-enter-active分别写上样式就行了。这里要注意的是 vue 中默认以v开头,如:v-enter,transition加个name属性,就可以用name属性值做开头,如:fade-enter。
现在这里两个class的意思是:
动画还没执行时,就已经有fade-enter,fade-enter-active,动画第一帧运行时fade-enter就会被移除,css效果opacity: 0就会变成opacity: 1,直到动画执行完fade-enter-active才会被移除,这期间它用transition对opacity进行监控,需要3s才能完成。
leave
隐藏的动画流程:
隐藏的第一个瞬间时,vue 会在dom上添加两个class,分别是v-leave和v-leave-active
运行到第二帧时,vue 会将v-leave移除,再添加一个v-leave-to
接着动画会继续执行,执行到结束的一瞬间,vue 会把之前添加的v-leave-to和v-leave-active都删除。
.fade-leave-to{ opacity: 0; } .fade-leave-active{ transition: opacity 3s; } <div id="root"> <transition name="fade"> <div v-if="show">hello world</div> </transition> <button @click="handleclick">按钮</button> </div> let vm = new vue({ el: '#root', data: { show:true }, methods: { handleclick(){ this.show = !this.show } } })
为什么加了这两个css动画效果就出来了呢?
从动画执行的第一个瞬间,到动画执行完毕,fade-leave-active这个class都存在。也就是在动画运行过程中,我要时刻监听div的opacity,一旦opacity发生变化,我要让让他在3s内执行完毕。
在第一个瞬间fade-leave的opacity为1,就是显示状态;第二个瞬间opacity为0了,此时要给它添加一个fade-leave-to的class,而fade-leave-active一直在监听opacity的变化,一旦opacity发生变化,会让它在3s内完成
自定义class
如果我不想用 vue 提供的这六个class,我想自定义一个class,该怎么实现呢?
.active,.leave{ transition: opacity 3s; }
vue 给我们提供了一个自定义的属性的方法,使用enter-active-class就能自定义一个enter类;使用leave-active-class就用自定义一个leave类。
<transition name="fade" enter-active-class="active" leave-active-class="leave" <div v-if="show">hello world</div> </transition>
利用这个特性,在项目中需使用复杂的css样式时,就可以引入第三方css样式库,这里介绍一个animate.css的库。
使用第三方库(animate.css),需要注意两点:
- 必须使用自定义class的方式
- 自定义class中必须有一个animated的class
<transition name="fade" enter-active-class="animated swing" leave-active-class="animated shake" <div v-if="show">hello world</div> </transition>
上面是按钮点击了才会出现动画效果,但此时需求想要实现一入场就有动画效果该怎么实现呢?
<transition name="fade" appear // 加上 appear 属性 enter-active-class="animated swing" leave-active-class="animated shake" appear-active-class="animated swing" //使用自定义属性 appear-active-class 就可以实现 <div v-if="show">hello world</div> </transition>
如需要在一进入就有动画,需要借助两个自定义属性:appear、appear-active-class来实现,看上面代码。
过渡transition和动画animation同时使用
当同时使用transition和animation动画时,动画时长是由谁来确定呢?
vue 提供了可手动设置,看下面代码
<transition name="fade" type="transition" //可手动设置动画时长以 transition 为准 appear enter-active-class="animated swing" leave-active-class="animated shake" appear-active-class="animated swing" <div v-if="show">hello world</div> </transition>
在transition标签中,可以使用type属性,它的用途是:如果同时有transition和animation时,此时将type设置为transition,它就以transition动画时长为准。
回到代码,现在需要自己定义动画的时长,该怎么实现呢?
<transition name="fade" :duration="10000" //动画总时长为 10s appear enter-active-class="animated swing" leave-active-class="animated shake" appear-active-class="animated swing" <div v-if="show">hello world</div> </transition>
vue 提供了duration的属性,可以自定义动画时长。
这个自定义动画时长,还可以设置的复杂一点:
<transition name="fade" :duration="{enter:5000,leave:10000}" //可分别设置 enter 动画时长和 leave 动画时长 appear enter-active-class="animated swing" leave-active-class="animated shake" appear-active-class="animated swing" <div v-if="show">hello world</div> </transition>
最后
在transition标签中中不光v-if能控制显示隐藏,v-show也能控制显示隐藏,甚至动态组件也行。只要在transition中标签中动画发生变化,都会有一个过渡效果
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
推荐阅读