Vue.js动画和过渡

vue中的过渡与动画

过滤

把需要添加动画效果的DIV放到transition标签

之后就会发生以下3个步骤

  1. 自动嗅探目标元素是否应用了 CSS 过渡或动画,如果是,在恰当的时机添加/删除 CSS 类名(等下要写的6个类名)。

  2. 如果过渡组件提供了 JavaScript 钩子函数,这些钩子函数将在恰当的时机被调用。

  3. 如果没有找到 JavaScript 钩子并且也没有检测到 CSS 过渡/动画,DOM 操作 (插入/删除) 在下一帧中立即执行。(注意:此指浏览器逐帧动画机制,和 Vue 的 nextTick 概念不同)

类名

v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。

v-enter-active:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的过程时间,延迟和曲线函数。

v-enter-to2.1.8版及以上 定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时 v-enter 被移除),在过渡/动画完成之后移除。

v-leave: 定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。

v-leave-active:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。

v-leave-to2.1.8版及以上 定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave 被删除),在过渡/动画完成之后移除。

插入

其实是看完了文档我也是一脸懵逼,看到这里其实有很多问题就出来了,下面我们一一列举一一解答

  1. 什么是定义进入/离开过渡
  2. 什么是在元素被插入之前,这个插入是插入到什么地方
  3. 当我们自身元素的css样式和v-enter,v-enter-to,v-leave,v-leave-to会出现重复吗?,是会覆盖还是不会覆盖,而且覆盖是谁覆盖谁,是自身的样式权重高呢,还是v-enter...呢?
  4. v-if和v-show的区别

1.什么是定义进入/离开过渡

进入过渡:元素显示的过程

离开过渡:元素离开的过程

以前我理解这个就是有一个地方无法理解,明明不管元素是显示还是隐藏他们都是一个过渡过程,那么其实他们(显示过程或离开过程)都是代表的进入过渡,对吧,我以前一直以为是文档表达的不清楚,但是后来我发现我自己太天真了,嘿嘿/斜眼笑。

2.什么是在元素被插入之前,这个插入是插入到什么地方

为什么我会有这个问题呢?因为v-if和v-show的区别大家应该都知道v-if是通过DOM的增删改变的显示隐藏,但是v-show呢?他可是通过display来显示和隐藏的啊,如果你说你只可以用v-if那是插入还差不多,但是你如果用的是v-show也可以达到效果,但是那你的文档的定义感觉有点问题啊是把?后来我发现我天真了,为什么呢?因为其实我们知道除了DOM树,还有一个浏览器的--渲染树,什么是渲染树呢?这里有我找的一篇文章,渲染树其实就是一个依赖DOM树,先有DOM树,再根据DOM去生成浏览器是渲染树,再文章中说了一句很关键的话:如果元素的display属性被设置成了none,或者如果元素的子孙继承了display:none,renderer不会被创建。节点的子类和display属性一起决定为该节点创建什么样的渲染器,说明了其实就算是v-show为false他的DOM依然在,但是也是是单单在DOM树上,在浏览器的渲染树上是不存在的所以才有了插入的在一个说法,并且第一个问题的进入/离开也有了很好的介绍,就是进入离开渲染树

3.当我们自身元素的css样式和v-enter,v-enter-to...是否会发出重复呢

  1. 重复是否会出错

  2. 发生覆盖,那么谁覆盖谁

这里我建议当我们要过渡一个元素的属性的时候,我们不要再这个元素上定义这个属性值

案例

过渡改变div的高度

<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script src="./node_modules/vue/dist/vue.js"></script>
  <style>
    .box{
      border: 1px solid saddlebrown;
      background-color: brown;
    }
    .box p{
      margin: 0;
      height: 156px;
      border: 1px solid saddlebrown;
    }
    .bounce-enter-active,.bounce-leave-active {
      transition: all 1s ease;
    }
    .bounce-leave,.bounce-enter-to{
      height: 156px;
    }
    .bounce-enter,.bounce-leave-to {
      height: 0;
      color: chartreuse;
    } 
  </style>
</head>

<body>
  <div id="example-2">
    <button @click="show = !show">Toggle show</button>
    <transition name="bounce">
      <div class="box" v-show='show'>
        <p>我的高度我156px;</p>
      </div>
    </transition>
  </div>
  <script>
    new Vue({
      el: '#example-2',
      data: {
        show: false
      }
    })
  </script>
</body>

</html>

这个案例是正常的情况,但是你们是否有注意到其实我这里的高度是设置再v-enter上面的?因为当我们设置再v-enter下面的时候就会出现问题?其实答案很简单就是样式发生了覆盖,导致高度一直都是156px还怎么过渡对吧,覆盖是根据css文件中样式书写的顺序,不是HTML上的顺序,大家可以去放下去试一下

  <style>
   
    /* .box p{
      margin: 0;
      height: 156px;
      border: 1px solid saddlebrown;
    } */
    .bounce-enter-active,.bounce-leave-active {
      transition: all 1s ease;
    }
    .bounce-leave,.bounce-enter-to{
      height: 156px;
    }
    .bounce-enter,.bounce-leave-to {
      height: 0;
      color: chartreuse;
    } 
    
    .box{
      border: 1px solid saddlebrown;
      background-color: brown;
      height: 156px;
    }
  </style>

也可以去打开F12去看样式中有被下划线,因为替代而被下划的样式;

4.v-if和v-show的区别

再vue中的javaScriot钩子函数(enter等下面的那些)监听的是浏览器渲染树中结构,所以v-if和v-show的区别其实是

v-if:先生成DOM树浏览器渲染树中的那个结构也是新生成的;

v-show:是修改了DOM树,浏览器中的渲染树是去更新渲染树

动画

为什么这里不用谢v-enter呢? 我们想一下其实我们动画里面是包含了开始状态和结束状态的,我们需要的只是执行那个动画,不用想过渡一样定义过渡的开始和结束值

<!DOCTYPE html>
<html>
 
<head>
  <meta charset="utf-8">
  <title>Vue中css动画的原理</title>
  <script src="./node_modules/vue/dist/vue.js"></script>
  <style>
    @keyframes bounce {
      0% {
        transform: scale(0);
      }
 
      50% {
        transform: scale(1.5);
      }
 
      100% {
        transform: scale(1);
      }
    }
 
    /* .fade-enter-active和.fade-leave-active代表一直都在的那个时间点 */
    .fade-enter-active {
      transform-origin: left center;
      /* 这里写这个因为div太宽了 */
      animation: bounce 1s;
    }
 
    .fade-leave-active {
      transform-origin: left center;
      animation: bounce 1s reverse;
    }
  </style>
</head>
 
<body>
  <div id="root">
    <transition name="fade">
      <div v-if="show">hello world</div>
    </transition>
    <button @click="click">切换</button>
  </div>
  <script>
    var root = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        click: function () {
          this.show = !this.show;
        }
      }
    })
  </script>
 
</body>
 
</html>

这里你会发现动画没写v-enter和v-leave-to为什么呢?

因为他是动画啊它不需要像过滤一样有初始和结束的差别来判断,他只需要知道什么时候执行v-enter-active 和v-leave-active
再执行里面的语句就可以了      

JavaScript钩子函数

除了用CSS过渡的动画来实现vue的组件过渡,还可以用JavaScript的钩子函数来实现,在钩子函数中直接操作DOM。我们可以在属性中声明以下钩子:

<transition
  v-on:before-enter="beforeEnter"
  v-on:enter="enter"
  v-on:after-enter="afterEnter"
  v-on:enter-cancelled="enterCancelled"
  v-on:before-leave="beforeLeave"
  v-on:leave="leave"
  v-on:after-leave="afterLeave"
  v-on:leave-cancelled="leaveCancelled"
>
</transition>
//这里的进入还是要强调一下是浏览器的渲染树里面

methods: {
  // 过渡进入
  // 设置过渡进入之前的组件状态
  beforeEnter: function (el) {
    // ...
  },
  // 设置过渡进入完成时的组件状态
  enter: function (el, done) {
    // ...
    done()
  },
  // 设置过渡进入完成之后的组件状态
  afterEnter: function (el) {
    // ...
  },
  enterCancelled: function (el) {
    // ...
  },
  // 过渡离开
  // 设置过渡离开之前的组件状态
  beforeLeave: function (el) {
    // ...
  },
  // 设置过渡离开完成时地组件状态
  leave: function (el, done) {
    // ...
    done()
  },
  // 设置过渡离开完成之后的组件状态
  afterLeave: function (el) {
    // ...
  },
  // leaveCancelled 只用于 v-show 中
  leaveCancelled: function (el) {
    // ...
  }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值