一.vue中的css动画原理:通过在某一时刻自动的往一些标签上增加一些样式来实现的。

看下面代码:

<body>
  <div id="root">
    <div v-if='show'>hello world</div>
    <button @click='handClick'>切换</button>
  </div>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        }
      }
    })
  </script>
</body>

 

     效果图:              当我们点击切换可以控制hello world 的显示和隐藏。

 

 

我们想实现hello world在隐藏的时候有渐隐渐显的功能:

    <!--transition标签的意思是它包裹的内容有动画的效果 -->
    <!-- transition他本身含有几个类,如:当我们给它设置了name的时候,类名就是fade-enter这样的;当没有设置name的时候,类名就是这样的v-enter。 -->
    <!-- 当一个元素被transition包裹的时候,vue会自动分析一下元素的css样式,然后构建一个动画的流程,在动画即将被执行的一瞬间,他会往内部的div上增加两个class名字,分别是fade-enter,和fade-enter-active。当动画第一帧执行结束之后,transition这个标签vue分析过,知道他是一个动画效果的时候,vue会在动画运行到第二帧的时候,帮助你干两件事情,这个时刻vue会把之前添加的fade-enter这个class给去掉,然后增加一个fade-enter-to这样的一个class的名字。接着动画会继续执行,执行到结束的这一瞬间,vue会干一件事情,他会把之前添加的fade-enter-active和fade-enter-to这两个Class给去除掉。

  

 

  <style type="text/css">
    .fade-enter{
      opacity: 0;
    }
    .fade-enter-active{
      transition: opacity 3s;
    }
  </style>
</head>
<body>
  <div id="root">
    <!-- 在动画还没有执行的一瞬间,在第一帧的时候,他会往div标签里面增加几个class样式,分别是fade-enter和fade-enter-active -->
    <transition name="fade">
      <div v-if='show'>hello world</div>
    </transition>
    <button @click='handClick'>切换</button>
  </div>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        }
      }
    })
  </script>
</body>

效果是点击切换,当hello world显示出来的时候会用3s的时间。

 

下面我们想要div从显示变为隐藏的过程实现一些动画

 

 

  <style type="text/css">
    .v-enter{
      opacity: 0;
    }
    .v-enter-active{
      transition: opacity 3s;
    }
    /* 此时v-leave这个时刻opacity是1,到第二帧的时候v-leave结束,v-leave-to开始,此时opacity开始变化,但是有v-leave-active监听着,所以不会让他瞬间改变,而是花三秒 */
    .v-leave-to{
      opacity: 0;
    }
    /* 在整个过程中,v-leave-active都监听着opacit这个属性,一旦他发生改变,就让他用三秒时间改变。 */
    .v-leave-active{
      transition: opacity 3s;
    }
  </style>
</head>
<body>
  <div id="root">
    <!-- 在动画还没有执行的一瞬间,他会往div标签里面增加几个class样式,分别是fade-enter和fade-enter-active -->
    <transition>
      <div v-if='show'>hello world</div>
    </transition>
    <button @click='handClick'>切换</button>
  </div>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        }
      }
    })
  </script>
</body>

效果是显示和隐藏都会有三秒的渐变过程。

 

二.在vue中使用animate.css库。

  在vue中使用@keyframes 

<style type="text/css">
    @keyframes one{
      0% {
        transform: scale(0);
      }
      50% {
        transform: scale(1.5);
      }
      100% {
        transform: scale(1);
      }
    }
    .v-enter-active{
      transform-origin: left center;
      animation: one 2s;
    }
    .v-leave-active{
      transform-origin: left center;
      animation: one 2s reverse;
    }
  </style>
</head>
<body>
  <div id="root">
    <transition>
      <div v-if="show">hello world</div>
    </transition>
    <button @click="handClick">切换</button>
  </div>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        }
      }
    })
  </script>
</body>

效果是点击切换,隐藏过程有一个放大再缩小的过程;显示的过程也有一个放大再缩小的过程。

 

如果想要自定义vue中动画的class类名,方法如下:

  <style type="text/css">
    @keyframes one{
      0% {
        transform: scale(0);
      }
      50% {
        transform: scale(1.5);
      }
      100% {
        transform: scale(1);
      }
    }
    .enter{
      transform-origin: left center;
      animation: one 2s;
    }
    .leave{
      transform-origin: left center;
      animation: one 2s reverse;
    }
  </style>
</head>
<body>
  <div id="root">
    <transition enter-active-class="enter" leave-active-class="leave">
      <div v-if="show">hello world</div>
    </transition>
    <button @click="handClick">切换</button>
  </div>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        }
      }
    })
  </script>
</body>

 

效果相同。

 

animate.css库里面有现成的代码,不需要我们自己写动画。用法:先下载animate.css这个库,再引入这个Css文件。然后入场动画和出场动画都要写animated这个class名字,但是这样还是没有效果,我们需要在animated 后面再加一个类名,从animate.css官网里找自己需要的动画类名即可。代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script type="text/javascript" src="./vue/vue.js"></script>
  <link rel="stylesheet" type="text/css" href="./animate.css">
</head>
<body>
  <div id="root">
    <transition enter-active-class="animated swing" leave-active-class="animated shake">
      <div v-if="show">hello world</div>
    </transition>
    <button @click="handClick">切换</button>
  </div>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        }
      }
    })
  </script>
</body>
</html>

效果和animate.css库的效果一样。

 

用animate.css库有几点需要注意:1.必须使用自定义的class名。2.class类里面必须包含animated这一个具体的类。3.想要怎么样的效果就将其类名写在第二个类名上即可。

 

三.在vue中同时使用过渡和动画

对于上面的效果,我们想要一开始刷新的时候显示过程就有动画效果,做法:添加appear 和appear-active-class即可:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script type="text/javascript" src="./vue/vue.js"></script>
  <link rel="stylesheet" type="text/css" href="./animate.css">
</head>
<body>
  <div id="root">
    <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>
    <button @click="handClick">切换</button>
  </div>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        }
      }
    })
  </script>
</body>
</html>

此时,刷新页面的时候就会有动画效果了。

下面我们想要既有动画,又有渐变的效果,我们可以添加两个类名,并给他俩设置渐变即可:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script type="text/javascript" src="./vue/vue.js"></script>
  <link rel="stylesheet" type="text/css" href="./animate.css">
  <style type="text/css">
    .fade-enter, .fade-leave-to{
      opacity: 0;
    }
    .fade-enter-active, .fade-leave-active{
      transition: opacity 3s;
    }
  </style>
</head>
<body>
  <div id="root">
    <transition 
      name="fade"
      appear
      enter-active-class="animated swing fade-enter-active" 
      leave-active-class="animated shake fade-leave-active"
      appear-active-class="animated swing"
    >
      <div v-if="show">hello world</div>
    </transition>
    <button @click="handClick">切换</button>
  </div>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        }
      }
    })
  </script>
</body>
</html>

上面的代码,从animate.css文件里面查到,swing的animation-duration是1s,而我们设置渐变的时长是3s,我们不知道这个动画时长到底是多少,所以我们给其添加属性type="transition",意思是动画时长以transition为准,即3s。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script type="text/javascript" src="./vue/vue.js"></script>
  <link rel="stylesheet" type="text/css" href="./animate.css">
  <style type="text/css">
    .fade-enter, .fade-leave-to{
      opacity: 0;
    }
    .fade-enter-active, .fade-leave-active{
      transition: opacity 3s;
    }
  </style>
</head>
<body>
  <div id="root">
    <transition 
      type="transition"
      name="fade"
      appear
      enter-active-class="animated swing fade-enter-active" 
      leave-active-class="animated shake fade-leave-active"
      appear-active-class="animated swing"
    >
      <div v-if="show">hello world</div>
    </transition>
    <button @click="handClick">切换</button>
  </div>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        }
      }
    })
  </script>
</body>
</html>

假如想要自定义动画时长,我们可以添加属性   :duration="5000"   意思是整个动画时长是5s。

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script type="text/javascript" src="./vue/vue.js"></script>
  <link rel="stylesheet" type="text/css" href="./animate.css">
  <style type="text/css">
    .fade-enter, .fade-leave-to{
      opacity: 0;
    }
    .fade-enter-active, .fade-leave-active{
      transition: opacity 3s;
    }
  </style>
</head>
<body>
  <div id="root">
    <transition 
      :duration="5000"
      type="transition"
      name="fade"
      appear
      enter-active-class="animated swing fade-enter-active" 
      leave-active-class="animated shake fade-leave-active"
      appear-active-class="animated swing"
    >
      <div v-if="show">hello world</div>
    </transition>
    <button @click="handClick">切换</button>
  </div>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        }
      }
    })
  </script>
</body>
</html>

:duration里面的内容还可以设置的复杂一点,:duration="{enter:5000 , leave:1000}"  意思是进场动画时长5s,出场动画时长1s。

 

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script type="text/javascript" src="./vue/vue.js"></script>
  <link rel="stylesheet" type="text/css" href="./animate.css">
  <style type="text/css">
    .fade-enter, .fade-leave-to{
      opacity: 0;
    }
    .fade-enter-active, .fade-leave-active{
      transition: opacity 3s;
    }
  </style>
</head>
<body>
  <div id="root">
    <transition 
      :duration="{enter:2000 , leave:5000}"
      type="transition"
      name="fade"
      appear
      enter-active-class="animated swing fade-enter-active" 
      leave-active-class="animated shake fade-leave-active"
      appear-active-class="animated swing"
    >
      <div v-if="show">hello world</div>
    </transition>
    <button @click="handClick">切换</button>
  </div>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        }
      }
    })
  </script>
</body>
</html>

 

四.vue中的js动画与Velocity.js的结合

 

vue之中提供给我们很多js动画的钩子,先介绍一下入场动画:

1.before-enter钩子,动画显示之前的过程

<body>
  <div id="root">
    <transition
      name="fade"
      @before-enter="handleEnter"
    >
      <div v-if="show">hello world</div>
    </transition>
    <button @click="handClick">toggle</button>
  </div>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        },
        handleEnter: function(){
          console.log(1)
        }
      }
    })
  </script>
</body>

效果,点击toggle,隐藏变成显示的过程中会执行before-enter这个事件,控制台打印出1。

实际上触发before-enter这个事件后调用的函数,它包含一个参数el,表示的是transition里面包含的dom元素。

<body>
  <div id="root">
    <transition
      name="fade"
      @before-enter="handleEnter"
    >
      <div v-if="show">hello world</div>
    </transition>
    <button @click="handClick">toggle</button>
  </div>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        },
        handleEnter: function(el){
          el.style.color="red"
        }
      }
    })
  </script>
</body>

效果图:   点击toggle,从隐藏变成显示了以后,字体变成了红色。

 

2.enter钩子,它触发的函数会包含两个参数,el和done,el同上:是它包含的dom元素;done是一个回调函数。    这个钩子是在before-enter执行完之后,动画真正开始执行的时候触发。

<body>
  <div id="root">
    <transition
      name="fade"
      @before-enter="handleBefore"
      @enter="handleEnter"
    >
      <div v-if="show">hello world</div>
    </transition>
    <button @click="handClick">toggle</button>
  </div>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        },
        handleBefore: function(el){
          el.style.color="red"
        },
        handleEnter: function(el, done){
          setTimeout(() => {
            el.style.color="green"
          }, 2000)
        }
      }
    })
  </script>
</body>

效果:从隐藏变成显示开始的时候字体是红色的,两秒之后字体变成了绿色。

要记得在动画执行结束之后要手动的调用done这个回调函数,相当于告诉vue,此时我这个动画已经执行完了,当done被执行完了,我们就会触发下一个钩子after-enter。

 

3.after-enter

<body>
  <div id="root">
    <transition
      name="fade"
      @before-enter="handleBefore"
      @enter="handleEnter"
      @after-enter="handleAfter"
    >
      <div v-if="show">hello world</div>
    </transition>
    <button @click="handClick">toggle</button>
  </div>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        },
        handleBefore: function(el){
          el.style.color="red"
        },
        handleEnter: function(el, done){
          setTimeout(() => {
            el.style.color="green"
            done()
          }, 2000)
        },
        handleAfter: function(el){
          el.style.color="black"
        }
      }
    })
  </script>
</body>

效果:从隐藏到显示的过程中,字体在先变成红色,接着变成绿色马上又变成黑色。

同理,有入场动画,就会有出场动画,分别是before-leave,leave,after-leave,用法和入场动画一样。

 

2.Velocity.js,它是js常用的动画库。先下载下来,接着通过script引入,

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script type="text/javascript" src="./vue/vue.js"></script>
  <script type="text/javascript" src="./velocity.js"></script>
</head>
<body>
  <div id="root">
    <transition
      name="fade"
      @before-enter="handleBefore"
      @enter="handleEnter"
      @after-enter="handleAfter"
    >
      <div v-if="show">hello world</div>
    </transition>
    <button @click="handClick">toggle</button>
  </div>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        },
        handleBefore: function(el){
          el.style.opacity = 0
        },
        handleEnter: function(el, done){
          Velocity(el, {opacity: 1}, {duration: 2000})
        },
        handleAfter: function(el){

        }
      }
    })
  </script>
</body>
</html>

效果是:隐藏到显示过程有两秒的渐变过程。

但是这样会有一个问题,我们没有执行done这个回调函数,下一个钩子就不能执行,改进:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>Document</title>
  <script type="text/javascript" src="./vue/vue.js"></script>
  <script type="text/javascript" src="./velocity.js"></script>
</head>
<body>
  <div id="root">
    <transition
      name="fade"
      @before-enter="handleBefore"
      @enter="handleEnter"
      @after-enter="handleAfter"
    >
      <div v-if="show">hello world</div>
    </transition>
    <button @click="handClick">toggle</button>
  </div>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        },
        handleBefore: function(el){
          el.style.opacity = 0
        },
        handleEnter: function(el, done){
          Velocity(el, {opacity: 1}, {duration: 2000, complete: done})
        },
        handleAfter: function(el){
          console.log(1)
        }
      }
    })
  </script>
</body>
</html>

效果:动画结束后一秒打印出1;

 

五.Vue中多个元素或组件的过渡

 

1.Vue中多个元素的过渡。

我们要实现一个效果,当show是true的时候显示hello world,当show是false的时候显示bye world。

<body>
  <div id="root">
    <transition>
      <div v-if="show">hello world</div>
      <div v-else>bye world</div>
    </transition>
    <button @click="handClick">toggle</button>
  </div>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        }
      }
    })
  </script>
</body>

效果就实现了。

我们还想加一点过渡效果

  <style type="text/css">
    .v-enter, .v-leave-to{
      opacity: 0;
    }
    .v-enter-active, .v-leave-active{
      transition: opacity 1s;
    }
  </style>
</head>
<body>
  <div id="root">
    <transition>
      <div v-if="show">hello world</div>
      <div v-else>bye world</div>
    </transition>
    <button @click="handClick">toggle</button>
  </div>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        }
      }
    })
  </script>
</body>

 

但是此时页面却没有过渡效果,原因是Vue他有一个复用dom的机制,导致上下的dom元素复用。解决办法:

 

加key值来消除这个复用的机制:

  <style type="text/css">
    .v-enter, .v-leave-to{
      opacity: 0;
    }
    .v-enter-active, .v-leave-active{
      transition: opacity 1s;
    }
  </style>
</head>
<body>
  <div id="root">
    <transition>
      <div v-if="show" key="hello">hello world</div>
      <div v-else key="bye">bye world</div>
    </transition>
    <button @click="handClick">toggle</button>
  </div>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        }
      }
    })
  </script>
</body>

vue在transition里还有一个mode的配置参数,来设置多个属性切换时的效果,如  mode="in-out",效果是显示的元素先进来,要隐藏的元素再隐藏。out-in则是隐藏的元素先隐藏,显示的元素再进入

  <style type="text/css">
    .v-enter, .v-leave-to{
      opacity: 0;
    }
    .v-enter-active, .v-leave-active{
      transition: opacity 1s;
    }
  </style>
</head>
<body>
  <div id="root">
    <transition mode="out-in">
      <div v-if="show" key="hello">hello world</div>
      <div v-else key="bye">bye world</div>
    </transition>
    <button @click="handClick">toggle</button>
  </div>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        }
      }
    })
  </script>
</body>

 

2.通过动态组件实现组件的过渡动画效果

 

先看一段代码:

  <style type="text/css">
    .v-enter, .v-leave-to{
      opacity: 0;
    }
    .v-enter-active, .v-leave-active{
      transition: opacity 1s;
    }
  </style>
</head>
<body>
  <div id="root">
    <transition mode="out-in">
      <child v-if="show"></child>
      <child-one v-else></child-one>
    </transition>
    <button @click="handClick">toggle</button>
  </div>
  <script type="text/javascript">
    Vue.component('child',{
      template: '<div>child</div>'
    })
    Vue.component('child-one',{
      template: '<div>child-one</div>'
    })

    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        }
      }
    })
  </script>
</body>

效果一样。

但是我们想通过动态组件来实现,代码如下:

  <style type="text/css">
    .v-enter, .v-leave-to{
      opacity: 0;
    }
    .v-enter-active, .v-leave-active{
      transition: opacity 1s;
    }
  </style>
</head>
<body>
  <div id="root">
    <transition mode="out-in">
      <component :is="type"></component>
    </transition>
    <button @click="handClick">toggle</button>
  </div>
  <script type="text/javascript">
    Vue.component('child',{
      template: '<div>child</div>'
    })
    Vue.component('child-one',{
      template: '<div>child-one</div>'
    })

    var vm = new Vue({
      el: '#root',
      data: {
        type: "child"
      },
      methods: {
        handClick: function(){
          this.type = this.type === 'child' ? 'child-one' :'child'
        }
      }
    })
  </script>
</body>

效果相同。

六.vue中的列表过渡。

<body>
  <div id="root">
    <div v-for="(item, index) of list" :key="item.id">
      {{item.title}}
    </div>
    <button @click="handClick">Add</button>
  </div>
  <script type="text/javascript">
    var count = 0;
    var vm = new Vue({
      el: '#root',
      data: {
        list: []
      },
      methods: {
        handClick: function(){
          this.list.push({
            id: count++,
            title: 'hello world'
          })
        }
      }
    })
  </script>
</body>

效果:每点击一下Add就增加一个hello world。

我们想实现一个列表的渲染效果

  <style type="text/css">
    .v-enter, .v-leave-to{
      opacity: 0;
    }
    .v-enter-active,.v-leave-active{
      transition: opacity 1s;
    }
  </style>
</head>
<body>
  <div id="root">
    <transition-group>
    <div v-for="(item, index) of list" :key="item.id">
      {{item.title}}
    </div>
    </transition-group>
    <button @click="handClick">Add</button>
  </div>
  <script type="text/javascript">
    var count = 0;
    var vm = new Vue({
      el: '#root',
      data: {
        list: []
      },
      methods: {
        handClick: function(){
          this.list.push({
            id: count++,
            title: 'hello world'
          })
        }
      }
    })
  </script>
</body>

效果就实现了,每点击一下,就增加一个hello world ,但是是过渡的效果。解释一下

<transition-group>
    <div v-for="(item, index) of list" :key="item.id">
      {{item.title}}
    </div>
</transition-group>

相当于:

<transition>
  <div></div>
</transition>
<transition>
  <div></div>
</transition> ......

给每个包裹的dom元素都增加了一个transition标签。

七.vue中的动画封装

 

先看一段代码,效果很简单,就是通过点击toggle实现child的显示和隐藏

 

  <style type="text/css">
    .v-enter, .v-leave-to{
      opacity: 0;
    }
    .v-enter-active,.v-leave-active{
      transition: opacity 1s;
    }
  </style>
</head>
<body>
  <div id="root">
    <transition>
      <div v-if="show">child</div>
    </transition>
    <button @click="handClick">toggle</button>
  </div>
  <script type="text/javascript">
    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        }
      }
    })
  </script>
</body>

下面我们把这个动画用组件封装起来:

  <style type="text/css">
    .v-enter, .v-leave-to{
      opacity: 0;
    }
    .v-enter-active,.v-leave-active{
      transition: opacity 1s;
    }
  </style>
</head>
<body>
  <div id="root">
    <row :show="show">
      <div>child</div>
    </row>
    <button @click="handClick">toggle</button>
  </div>
  <script type="text/javascript">
    Vue.component('row',{
      props: ['show'],
      template: `<transition>
                  <slot v-if="show"></slot>
                 </transition>
                `
    })

    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        }
      }
    })
  </script>
</body>

 

想要用的时候呢,复制dom就可以,如

  <style type="text/css">
    .v-enter, .v-leave-to{
      opacity: 0;
    }
    .v-enter-active,.v-leave-active{
      transition: opacity 1s;
    }
  </style>
</head>
<body>
  <div id="root">
    <row :show="show">
      <div>child</div>
    </row>
    <row :show="show">
      <h2>child</h2>
    </row>
    <button @click="handClick">toggle</button>
  </div>
  <script type="text/javascript">
    Vue.component('row',{
      props: ['show'],
      template: `<transition>
                  <slot v-if="show"></slot>
                 </transition>
                `
    })

    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        }
      }
    })
  </script>
</body>

 

 

 

我们除了上面那种封装方法,还有别的封装方法,可以把样式也封装起来。也比较推荐这种动画封装方式,因为他把完整的动画实现过程封装在里面。

<body>
  <div id="root">
    <row :show="show">
      <div>child</div>
    </row>
    <row :show="show">
      <h2>child</h2>
    </row>
    <button @click="handClick">toggle</button>
  </div>
  <script type="text/javascript">
    Vue.component('row',{
      props: ['show'],
      template: `<transition @before-enter="handleBefore" @enter="handleEnter"> 
                  <slot v-if="show"></slot>
                 </transition>
                `,
      methods: {
        handleBefore: function(el){
          el.style.color = "red"
        },
        handleEnter: function(el,done){
          setTimeout(() => {
            el.style.color = "green"
            done()
          }, 2000)
        }
      }
    })

    var vm = new Vue({
      el: '#root',
      data: {
        show: true
      },
      methods: {
        handClick: function(){
          this.show = !this.show
        }
      }
    })
  </script>
</body>

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

Logo

前往低代码交流专区

更多推荐