概述
Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。 包括以下工具:
- 在 CSS 过渡和动画中自动应用 class
- 可以配合使用第三方 CSS 动画库,如 Animate.css
- 在过渡钩子函数中使用 JavaScript 直接操作 DOM
- 可以配合使用第三方 JavaScript 动画库,如 Velocity.js
上一篇章讲解了使用第三方CSS动画库Animate.css来设置动画效果,本章节来看看如何使用钩子函数来实现。
那么前面的方法都可以实现动画效果了,为什么还要特定用多一个JavaScript的钩子方法来设置呢?主要是因为无法单独设置一个入场和出场中某个步骤的动画效果。
例如:单独只设置入场或者单独只设置出场的动画效果。对于这种动画效果,应用的场景例如加入购物车这样的情况,按照之前的使用CSS的方法是无法设置出来的。
下面来看看官网中的使用介绍。
JavaScript 钩子函数
可以在属性中声明 JavaScript 钩子
<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>可以看到这里使用v-on绑定了动画过程的多个钩子函数,具体的动画效果只要在对应的钩子函数进行编写即可。
// ...
methods: {
  // --------
  // 进入中
  // --------
  beforeEnter: function (el) {
    // ...
  },
  // 当与 CSS 结合使用时
  // 回调函数 done 是可选的
  enter: function (el, done) {
    // ...
    done()
  },
  afterEnter: function (el) {
    // ...
  },
  enterCancelled: function (el) {
    // ...
  },
  // --------
  // 离开时
  // --------
  beforeLeave: function (el) {
    // ...
  },
  // 当与 CSS 结合使用时
  // 回调函数 done 是可选的
  leave: function (el, done) {
    // ...
    done()
  },
  afterLeave: function (el) {
    // ...
  },
  // leaveCancelled 只用于 v-show 中
  leaveCancelled: function (el) {
    // ...
  }
}这些钩子函数可以结合 CSS transitions/animations 使用,也可以单独使用。
当只用 JavaScript 过渡的时候,在 enter 和 leave 中必须使用 done 进行回调。否则,它们将被同步调用,过渡会立即完成。
推荐对于仅使用 JavaScript 过渡的元素添加 v-bind:css="false",Vue 会跳过 CSS 的检测。这也可以避免过渡过程中 CSS 的影响。
一个使用 Velocity.js 的简单例子:
<!--
Velocity 和 jQuery.animate 的工作方式类似,也是用来实现 JavaScript 动画的一个很棒的选择
-->
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
<div id="example-4">
  <button @click="show = !show">
    Toggle
  </button>
  <transition
    v-on:before-enter="beforeEnter"
    v-on:enter="enter"
    v-on:leave="leave"
    v-bind:css="false"
  >
    <p v-if="show">
      Demo
    </p>
  </transition>
</div>new Vue({
  el: '#example-4',
  data: {
    show: false
  },
  methods: {
    beforeEnter: function (el) {
      el.style.opacity = 0
      el.style.transformOrigin = 'left'
    },
    enter: function (el, done) {
      Velocity(el, { opacity: 1, fontSize: '1.4em' }, { duration: 300 })
      Velocity(el, { fontSize: '1em' }, { complete: done })
    },
    leave: function (el, done) {
      Velocity(el, { translateX: '15px', rotateZ: '50deg' }, { duration: 600 })
      Velocity(el, { rotateZ: '100deg' }, { loop: 2 })
      Velocity(el, {
        rotateZ: '45deg',
        translateY: '30px',
        translateX: '30px',
        opacity: 0
      }, { complete: done })
    }
  }
})下面使用钩子函数来实现一个运动半场的动画效果。
使用JavaScript钩子函数实现一个小球半场动画
1.首先写一个点击按钮【购物】,然后一个红色小球,用于展示购物的效果
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--  1.导入vue.js库  -->
    <script src="lib/vue.js"></script>
    <!--  编写小球的显示样式  -->
    <style>
        #boll{
            margin-top: 10px;
            width: 15px;
            height: 15px;
            border-radius: 50%;
            background: lightpink;
        }
    </style>
</head>
<body>
    <div id="app">
        <!-- 使用v-on绑定click事件执行切换show变量,用于控制下面p标签的v-if -->
        <button @click="show = !show">
            加入购物车
        </button>
        <!-- 设置动画小球 -->
        <transition>
            <div v-if="show" id="boll"></div>
        </transition>
    </div>
    <script>
        // 2\. 创建一个Vue的实例
        var vm = new Vue({
            el: '#app',
            data: {
                show: true
            },
        })
    </script>
</body>
</html>浏览器查看如下:
 
 
  
   
   
    
 
   
  
   image-20200202111435190
   
  
 
2.使用v-on设置进入变量的钩子函数
 
  
   
    
    
     
 
    
   
    image-20200202111811425
    
   
  
3.在对应的钩子函数打印对应信息,查看相关钩子的执行情况
 
   
    
     
     
      
 
     
    
     image-20200202112646624
     
    
   
在浏览器中查看,点击按钮,当切换v-if显示小球的时候,对应的钩子函数会如何执行,执行哪些钩子函数。如下:
 
    
     
      
      
       
 
      
     
      image-20200202113150291
      
     
    
4.在对应的钩子函数中,编写小球的动画js代码
 
     
      
       
       
        
 
       
      
       image-20200202114818725
       
      
     
在enter钩子函数中的el.offsetWidth很重要,如果不写则不会出来动画效果,当然写其他offsetHeight也是可以的。
效果如下:
 
      
       
        
        
         
 
        
       
        image-20200202115009434
        
       
       
        
         
         
          
 
         
        
          
         
        
到这里已经实现了小球通过购物车点击,触发v-if显示入场动画效果。
完整示例代码
<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
    <!--  1.导入vue.js库  -->
    <script src="lib/vue.js"></script>
    <!--  编写小球的显示样式  -->
    <style>
        #boll{
            margin-top: 10px;
            width: 15px;
            height: 15px;
            border-radius: 50%;
            background: lightpink;
        }
    </style>
</head>
<body>
    <div id="app">
        <!-- 使用v-on绑定click事件执行切换show变量,用于控制下面p标签的v-if -->
        <button @click="show = !show">
            加入购物车
        </button>
        <!-- 设置动画小球 -->
        <transition
                v-on:before-enter="beforeEnter"
                v-on:enter="enter"
                v-on:after-enter="afterEnter"
                v-on:enter-cancelled="enterCancelled"
        >
            <div v-if="show" id="boll"></div>
        </transition>
    </div>
    <script>
        // 2\. 创建一个Vue的实例
        var vm = new Vue({
            el: '#app',
            data: {
                show: true
            },
            methods:{
                // --------
                // 进入中
                // --------
                beforeEnter: function (el) {
                    // 开始准备进入动画状态
                    console.log("执行进入动画中的beforeEnter钩子函数");
                    // 设置小球开始动画之前的,起始位置
                    el.style.transform = "translate(0, 0)";
                },
                // 当与 CSS 结合使用时
                // 回调函数 done 是可选的
                enter: function (el, done) {
                    // 已经进入动画状态,用于设置动画效果
                    console.log("执行进入动画中的enter钩子函数");
                    // 这句话,没有实际的作用,但是,如果不写,出不来动画效果;
                    // 可以认为 el.offsetWidth 会强制动画刷新
                    el.offsetWidth;
                    // enter 表示动画 开始之后的样式,这里,可以设置小球完成动画之后的,结束状态
                    el.style.transform = "translate(150px, 450px)";
                    el.style.transition = 'all 1s ease';
                    // 执行完毕,使用done方法回调afterEnter
                    done()
                },
                afterEnter: function (el) {
                    // 进入动画状态之后,执行结束恢复的操作
                    console.log("执行进入动画中的afterEnter钩子函数");
                    // 执行动画完毕后,再次隐藏小球
                    this.show = !this.show
                },
                enterCancelled: function (el) {
                    // 当取消进入动画状态的时候执行
                    console.log("执行进入动画中的enterCancelled钩子函数");
                },
            }
        })
    </script>
</body>
</html> 
         
          
           
           
            
 
           
          
            
           
          
         
        
       
      
     
    
   
  
                









