Vue中CSS动画原理的实现


Posted in Javascript onFebruary 13, 2019

下面这段代码,是点击按钮实现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中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才能完成。

Vue中CSS动画原理的实现

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),需要注意两点:

  1. 必须使用自定义class的方式
  2. 自定义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中标签中动画发生变化,都会有一个过渡效果

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
JSON 和 JavaScript eval使用说明
Jun 13 Javascript
JavaScript实现函数返回多个值的方法
Jun 09 Javascript
jQuery实现的鼠标经过时变宽的效果(附demo源码)
Apr 28 Javascript
获取JavaScript异步函数的返回值
Dec 21 Javascript
js Canvas绘制圆形时钟教程
Feb 06 Javascript
JavaScript简介_动力节点Java学院整理
Jun 26 Javascript
详解vue中computed 和 watch的异同
Jun 30 Javascript
angular写一个列表的选择全选交互组件的示例
Jan 22 Javascript
vue2.0实现音乐/视频播放进度条组件
Jun 06 Javascript
angular4应用中输入的最小值和最大值的方法
May 17 Javascript
Vue 微信端扫描二维码苹果端却只能保存图片问题(解决方法)
Jan 19 Javascript
Java 生成随机字符的示例代码
Jan 13 Javascript
Vue中JS动画与Velocity.js的结合使用
Feb 13 #Javascript
JavaScript中.min.js和.js文件的区别讲解
Feb 13 #Javascript
node.js微信小程序配置消息推送的实现
Feb 13 #Javascript
vue实现购物车抛物线小球动画效果的方法详解
Feb 13 #Javascript
Jquery实现无缝向上循环滚动列表的特效
Feb 13 #jQuery
vuex实现的简单购物车功能示例
Feb 13 #Javascript
jquery无缝图片轮播组件封装
Nov 25 #jQuery
You might like
微信公众号实现扫码获取微信用户信息(网页授权)
2019/04/09 PHP
30分钟就入门的正则表达式基础教程
2013/02/25 Javascript
node.js应用后台守护进程管理器Forever安装和使用实例
2014/06/01 Javascript
javascript浏览器兼容教程之事件处理
2014/06/09 Javascript
简单易用的倒计时js代码
2014/08/04 Javascript
jQuery中andSelf()方法用法实例
2015/01/08 Javascript
Bootstrap嵌入jqGrid,使你的table牛逼起来
2016/05/05 Javascript
AngularJS上拉加载问题解决方法
2016/05/23 Javascript
浅谈layer的iframe弹窗给里面的标签赋值的问题
2016/11/10 Javascript
JavaScript输入框字数实时统计更新
2017/06/17 Javascript
jQuery实现浏览器之间跳转并传递参数功能【支持中文字符】
2018/03/28 jQuery
vuejs实现标签选项卡动态更改css样式的方法
2018/05/31 Javascript
JavaScript之scrollTop、scrollHeight、offsetTop、offsetHeight等属性学习笔记
2020/07/15 Javascript
vue render函数动态加载img的src路径操作
2020/10/26 Javascript
[01:52]PWL S2开团时刻第四期——DOTA2成语故事
2020/12/03 DOTA
[52:20]DOTA2-DPC中国联赛正赛 SAG vs XGBO3 第一场 3月5日
2021/03/11 DOTA
python实现12306火车票查询器
2017/04/20 Python
Pytorch 多块GPU的使用详解
2019/12/31 Python
python字符串常用方法及文件简单读写的操作方法
2020/03/04 Python
Python3中的tuple函数知识点讲解
2021/01/03 Python
HTML5 画布canvas使用方法
2016/03/18 HTML / CSS
联想西班牙官网:Lenovo西班牙
2018/08/28 全球购物
Java中实现多态的机制
2015/08/09 面试题
应用电子技术专业个人求职信
2013/09/21 职场文书
电子商务专业个人的自我评价
2013/12/19 职场文书
职业生涯规划书的格式
2013/12/29 职场文书
区优秀教师事迹材料
2014/02/10 职场文书
应届大专毕业生自我鉴定
2014/04/08 职场文书
员工合理化建议书
2014/05/19 职场文书
优秀教师申报材料
2014/12/16 职场文书
2015驻村干部工作总结
2015/04/07 职场文书
会计岗位工作总结
2015/08/12 职场文书
2016年师德先进个人事迹材料
2016/02/29 职场文书
MongoDB日志切割的三种方式总结
2021/09/15 MongoDB
Spring this调用当前类方法无法拦截的示例代码
2022/03/20 Java/Android
Python中np.random.randint()参数详解及用法实例
2022/09/23 Python