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 相关文章推荐
TypeScript 学习笔记之基本类型
Jun 19 Javascript
解决jquery实现的radio重新选中的问题
Jul 03 Javascript
JavaScript类型系统之基本数据类型与包装类型
Jan 06 Javascript
js改变style样式和css样式的简单实例
Jun 28 Javascript
AngularJS API之copy深拷贝详解及实例
Sep 14 Javascript
js定时器实例分享
Dec 20 Javascript
又一款MVVM组件 构建自己的Vue组件(2)
Mar 13 Javascript
React-Native中props具体使用详解
Sep 04 Javascript
详解如何使用webpack打包JS
Jun 21 Javascript
layui自定义工具栏的方法
Sep 19 Javascript
关于layui导航栏不展示下拉列表的解决方法
Sep 25 Javascript
Bootstrap告警框(alert)实现弹出效果和短暂显示后上浮消失的示例代码
Aug 27 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
在PHP3中实现SESSION的功能(三)
2006/10/09 PHP
php中选择什么接口(mysql、mysqli)访问mysql
2013/02/06 PHP
php中实现xml与mysql数据相互转换的方法
2014/12/25 PHP
用php代码限制国内IP访问我们网站
2015/09/26 PHP
Yii实现的多级联动下拉菜单
2016/07/13 PHP
input 输入框内的输入事件详细分析
2010/03/17 Javascript
百度Popup.js弹出框进化版 拖拽小框架发布 兼容IE6/7/8,Firefox,Chrome
2010/04/13 Javascript
javascript深入理解js闭包
2010/07/03 Javascript
javascript获取作用在元素上面的样式属性代码
2012/09/20 Javascript
jQuery+PHP实现动态数字展示特效
2015/03/14 Javascript
javascript使用闭包模拟对象的私有属性和方法
2016/10/05 Javascript
jQuery progressbar通过Ajax请求实现后台进度实时功能
2016/10/11 Javascript
vue2.0实现倒计时的插件(时间戳 刷新 跳转 都不影响)
2017/03/30 Javascript
基于JS实现仿京东搜索栏随滑动透明度渐变效果
2017/07/10 Javascript
vue 2.1.3 实时显示当前时间,每秒更新的方法
2018/09/16 Javascript
JavaScript实现页面中录音功能的方法
2019/06/04 Javascript
[00:43]拉比克至宝魔导师密钥展示
2018/12/20 DOTA
Python中文编码那些事
2014/06/25 Python
使用Nginx+uWsgi实现Python的Django框架站点动静分离
2016/03/21 Python
python Django批量导入数据
2016/03/25 Python
详解python的几种标准输出重定向方式
2016/08/15 Python
python抓取文件夹的所有文件
2018/02/27 Python
python中dict使用方法详解
2019/07/17 Python
Django 开发调试工具 Django-debug-toolbar使用详解
2019/07/23 Python
树莓派4B+opencv4+python 打开摄像头的实现方法
2019/10/18 Python
Python3 获取文件属性的方式(时间、大小等)
2020/03/12 Python
解决pycharm安装第三方库失败的问题
2020/05/09 Python
python3.7调试的实例方法
2020/07/21 Python
Python+Selenium随机生成手机验证码并检查页面上是否弹出重复手机号码提示框
2020/09/21 Python
详解基于python的全局与局部序列比对的实现(DNA)
2020/10/07 Python
解决img标签上下出现间隙的方法
2016/12/14 HTML / CSS
美国受欢迎的女性牛仔裤品牌:DL1961
2016/11/12 全球购物
贪睡宠物用品:Snoozer Pet Products
2020/02/04 全球购物
如何写自我鉴定
2014/03/19 职场文书
SQL Server数据库查询出现阻塞之性能调优
2022/04/10 SQL Server
JavaScript中10个Reduce常用场景技巧
2022/06/21 Javascript