VUE2 第五天學習--過渡效果

閱讀目錄javascript

1.理解VUE---過渡效果css

1. 過渡的-css-類名
會有4個(css) 類名在 enter/leave 在過渡中切換。
1. v-enter: 進入過渡的開始狀態。在元素被插入時生效,在下一個幀移除。
2. v-enter-active: 進入過渡的結束狀態。在元素被插入時生效,在 transition/animation 完成以後移除。
3. v-leave 離開過渡的開始狀態。在離開過渡被觸發時生效,在下一個幀移除。
4. v-leave-active 離開過渡的結束狀態。在離開過渡被觸發時生效,在 transition/animation 完成以後移除。
看以下圖所示:html

在enter/leave 過渡中切換的類名,v- 是類名的前綴,使用 <transition name="my-transition"> 能夠重置前綴,好比 v-enter 替換爲 my-transition-enter。
看以下demovue

<!DOCTYPE html>
<html>
  <head>
    <title>演示Vue</title>
    <style>
      .fade-enter-active, .fade-leave-active {
        transition: opacity .5s
      }
      .fade-enter, .fade-leave-active {
        opacity: 0
      }
    </style>
  </head>
  <body>
    <div id='app'>
      <button v-on:click="show = !show">toggle</button>
      <transition name='fade'>
        <p v-if="show">hello</p>
      </transition>
    </div>
  </body>
  <script src="./vue.js"></script>
  <script type="text/javascript">
    new Vue({
      el: '#app',
      data: {
        show: true
      }
    })
  </script>
</html>

查看效果java

如上代碼; 給transition標籤 定義了一個name屬性,所以過渡的css類名中的前綴v被替換成fade,定義了 .fade-enter-active, .fade-leave-active {transition: opacity .5s } 過渡動畫,定義進入過渡的結束狀態和離開過渡的結束狀態 爲透明度0 在0.5s以內完成。git

咱們還能夠定義以下的css,實現動畫,以下css代碼:github

.fade-enter-active {
  transition: all .5s ease;
}
.fade-leave-active {
  transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.fade-enter, .fade-leave-active {
  transform: translateX(10px);
  opacity: 0;
}

查看效果web

2. css動畫
css動畫用法同css過渡同樣, 區別是在動畫中 v-enter 類名在節點插入DOM後不會當即刪除,而是在animationend事件觸發時刪除。以下代碼也能夠用在css動畫下。ajax

<!DOCTYPE html>
<html>
  <head>
    <title>演示Vue</title>
    <style>
      .fade-enter-active {
        animation: fade-in .5s;
      }
      .fade-leave-active {
        animation: fade-out .5s;
      }
      @keyframes fade-in {
        0% {
          transform: scale(0);
        }
        50% {
          transform: scale(1.5);
        }
        100% {
          transform: scale(1);
        }
      }
      @keyframes fade-out {
        0% {
          transform: scale(1);
        }
        50% {
          transform: scale(1.5);
        }
        100% {
          transform: scale(0);
        }
      }
    </style>
  </head>
  <body>
    <div id='app'>
      <button v-on:click="show = !show">toggle</button>
      <transition name='fade'>
        <p v-if="show">hello</p>
      </transition>
    </div>
  </body>
  <script src="./vue.js"></script>
  <script type="text/javascript">
    new Vue({
      el: '#app',
      data: {
        show: true
      }
    })
  </script>
</html>

查看效果app

3. 自定義過渡類名
上面的四個過渡類名都是根據transition的name屬性自動生成的,下面咱們能夠經過如下特性來自定義過渡類名。

enter-class
enter-active-class
leave-class
leave-active-class

以上的優先級都高於普通類名,經過以上的 我能夠自定義類名寫不一樣的樣式了,以下代碼:
以下使用的animate.css裏面的樣式實現動畫:以下代碼:

<!DOCTYPE html>
<html>
  <head>
    <title>演示Vue</title>
    <link href="https://unpkg.com/animate.css@3.5.1/animate.min.css" rel="stylesheet" type="text/css">
  </head>
  <body>
    <div id='app'>
      <button v-on:click="show = !show">toggle</button>
      <transition
        name="custom-classes-transition"
        enter-active-class="animated tada"
        leave-active-class="animated bounceOutRight"
      >
        <p v-if="show">hello</p>
      </transition>
    </div>
  </body>
  <script src="./vue.js"></script>
  <script type="text/javascript">
    new Vue({
      el: '#app',
      data: {
        show: true
      }
    })
  </script>
</html>

查看效果

4. 多個組件的過渡
多個組件的過渡能夠使用動態組件實現,以下代碼:

<!DOCTYPE html>
<html>
  <head>
    <title>演示Vue</title>
    <style>
      .component-fade-enter-active, .component-fade-leave-active {
        transition: opacity .3s ease;
      }
      .component-fade-enter, .component-fade-leave-active {
        opacity: 0;
      }
    </style>
  </head>
  <body>
    <div id='app'>
      <input v-model='view' type='radio' value='v-a' name="view" />
      <label for='a'>A</label>
      <input v-model='view' type='radio' value='v-b' name='view' />
      <label for='b'>B</label>
      <transition name='component-fade' mode='out-in'>
        <component v-bind:is='view'></component>
      </transition>
    </div>
  </body>
  <script src="./vue.js"></script>
  <script type="text/javascript">
    new Vue({
      el: '#app',
      data: {
        view: 'v-a'
      },
      components: {
        'v-a': {
          template: '<div>Component A</div>'
        },
        'v-b': {
          template: '<div>Component B</div>'
        }
      }
    })
  </script>
</html>

查看效果

5. 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>
new Vue({
  el: '#app',
  data: {
    view: 'v-a'
  },
  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: function(el) {
      // ....
    }
  }
})

注意:
1. 只用 JavaScript 過渡的時候, 在 enter 和 leave 中,回調函數 done 是必須的 。 不然,它們會被同步調用,過渡會當即完成。
2. 推薦對於僅使用 JavaScript 過渡的元素添加 v-bind:css="false",Vue 會跳過 CSS 的檢測。這也能夠避免過渡過程當中 CSS 的影響。
下面是vue教程上Velocity.js的一個demo,以下代碼:

<!DOCTYPE html>
<html>
  <head>
    <title>演示Vue</title>
    <style>
    </style>
  </head>
  <body>
    <div id='app'>
      <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>
  </body>
  <script src="./vue.js"></script>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.js"></script>
  <script type="text/javascript">
    new Vue({
      el: '#app',
      data: {
        show: true
      },
      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 })
        }
      }
    })
  </script>
</html>

查看效果 

理解過渡模式:
以下demo

<!DOCTYPE html>
<html>
  <head>
    <title>演示Vue</title>
    <style>
      .no-mode-fade-enter-active, .no-mode-fade-leave-active {
        transition: opacity .5s
      }
      .no-mode-fade-enter, .no-mode-fade-leave-active {
        opacity: 0;
      }
    </style>
  </head>
  <body>
    <div id='app'>
      <transition name='no-mode-fade'>
        <button v-if='on' key='on' @click='on=false'>on</button>
        <button v-else='' key='off' @click='on=true'>off</button>
      </transition>
    </div>
  </body>
  <script src="./vue.js"></script>
  <script type="text/javascript">
    new Vue({
      el: '#app',
      data: {
        on: false
      }
    })
  </script>
</html>

查看效果 

運行一下,在上面的on按鈕 和 off按鈕的過渡中,兩個按鈕都被重繪了,一個離開過渡的時候另外一個開始進入過渡。這是 <transition> 的默認行爲 - 進入和離開同時發生。
可是咱們在元素絕對定位在彼此之上的時候運行正常:以下代碼:

<!DOCTYPE html>
<html>
  <head>
    <title>演示Vue</title>
    <style>
      .wrap {
        position: relative;
        height: 18px;
      }
      .wrap button {
        position: absolute;
      }
      .no-mode-fade-enter-active, .no-mode-fade-leave-active {
        transition: opacity .5s
      }
      .no-mode-fade-enter, .no-mode-fade-leave-active {
        opacity: 0;
      }
    </style>
  </head>
  <body>
    <div id='app'>
      <div class='wrap'>
        <transition name='no-mode-fade'>
          <button v-if='on' key='on' @click='on=false'>on</button>
          <button v-else='' key='off' @click='on=true'>off</button>
        </transition>
      </div>
    </div>
  </body>
  <script src="./vue.js"></script>
  <script type="text/javascript">
    new Vue({
      el: '#app',
      data: {
        on: false
      }
    })
  </script>
</html>

查看效果 

咱們加上 translate 讓它們運動像滑動過渡:代碼以下:

<!DOCTYPE html>
<html>
  <head>
    <title>演示Vue</title>
    <style>
      .wrap {
        position: relative;
        height: 18px;
      }
      .wrap button {
        position: absolute;
      }
      .no-mode-fade-enter-active, .no-mode-fade-leave-active {
        transition: all 1s
      }
      .no-mode-fade-enter, .no-mode-fade-leave-active {
        opacity: 0;
      }
      .no-mode-fade-enter {
        transform: translateX(31px);
      }
      .no-mode-fade-leave-active {
        transform: translateX(-31px);
      }
    </style>
  </head>
  <body>
    <div id='app'>
      <div class='wrap'>
        <transition name='no-mode-fade'>
          <button v-if='on' key='on' @click='on=false'>on</button>
          <button v-else='' key='off' @click='on=true'>off</button>
        </transition>
      </div>
    </div>
  </body>
  <script src="./vue.js"></script>
  <script type="text/javascript">
    new Vue({
      el: '#app',
      data: {
        on: false
      }
    })
  </script>
</html>

查看效果 

同時生效的進入和離開的過渡不能知足全部要求,因此 Vue 提供了 過渡模式
in-out: 新元素先進行過渡,完成以後當前元素過渡離開。
out-in: 當前元素先進行過渡,完成以後新元素過渡進入。
用 out-in 重寫以前的開關按鈕過渡:以下代碼:

<!DOCTYPE html>
<html>
  <head>
    <title>演示Vue</title>
    <style>
      .no-mode-fade-enter-active, .no-mode-fade-leave-active {
        transition: opacity .5s
      }
      .no-mode-fade-enter, .no-mode-fade-leave-active {
        opacity: 0;
      }
    </style>
  </head>
  <body>
    <div id='app'>
      <div class='wrap'>
        <transition name='no-mode-fade' mode='out-in'>
          <button v-if='on' key='on' @click='on=false'>on</button>
          <button v-else='' key='off' @click='on=true'>off</button>
        </transition>
      </div>
    </div>
  </body>
  <script src="./vue.js"></script>
  <script type="text/javascript">
    new Vue({
      el: '#app',
      data: {
        on: false
      }
    })
  </script>
</html>

查看效果 

in-out 滑動淡出demo以下:

<!DOCTYPE html>
<html>
  <head>
    <title>演示Vue</title>
    <style>
      .wrap {
        position: relative;
        height: 18px;
      }
      .wrap button {
        position: absolute;
      }
      .no-mode-fade-enter-active, .no-mode-fade-leave-active {
        transition: all .5s
      }
      .no-mode-fade-enter, .no-mode-fade-leave-active {
        opacity: 0;
      }
      .no-mode-fade-enter {
        transform: translateX(31px);
      }
      .no-mode-fade-leave-active {
        transform: translateX(-31px);
      }
    </style>
  </head>
  <body>
    <div id='app'>
      <div class='wrap'>
        <transition name='no-mode-fade' mode='in-out'>
          <button v-if='on' key='on' @click='on=false'>on</button>
          <button v-else='' key='off' @click='on=true'>off</button>
        </transition>
      </div>
    </div>
  </body>
  <script src="./vue.js"></script>
  <script type="text/javascript">
    new Vue({
      el: '#app',
      data: {
        on: false
      }
    })
  </script>
</html>

查看效果 

5. VUE列表過渡實現輪播圖
列表過渡使用 <transition-group> 組件,不一樣於 <transition>:
1. 它會以一個真實元素呈現:默認爲一個 <span>。你也能夠經過 tag 特性更換爲其餘元素。
2. 內部元素 老是須要 提供惟一的 key 屬性值。

<!DOCTYPE html>
<html>
  <head>
    <title>演示Vue</title>
    <style>
      * { margin:0; padding:0;}
      .carousel-wrap {
        position: relative;
        height: 280px;
        width: 520px;
        overflow: hidden;
        // 刪除
        background-color: #fff;
      }
      .slide-ul {
        width: 100%;
        height: 100%;
      }
      .slide-ul li {
        position: absolute;
        width: 100%;
        height: 100%;
      }
      .slide-ul li img {
        width: 100%;
        height: 100%;
      }
      .carousel-items {
        position: absolute;
        z-index: 10;
        bottom: 10px;
        width: 100%;
        margin: 0 auto;
        text-align: center;
        font-size: 0;
      }
      .carousel-items span {
        display: inline-block;
        height: 6px;
        width: 30px;
        margin: 0 3px;
        background-color: #b2b2b2;
        cursor: pointer;
      }
      .carousel-items span.active {
        background-color: red;
      }
      .list-enter-active {
        transition: all 1s ease;
        transform: translateX(0)
      }

      .list-leave-active {
        transition: all 1s ease;
        transform: translateX(-100%)
      }

      .list-enter {
        transform: translateX(100%)
      }

      .list-leave {
        transform: translateX(0)
      }
    </style>
  </head>
  <body>
    <div id='carousel' class='carousel-wrap'>
      <transition-group tag='ul' class='slide-ul' name='list'>
        <li v-for='(list, index) in slideList' :key='index' v-show='index===currentIndex' @mouseenter='stop' @mouseleave='go'>
          <a :href='list.href'>
            <img :src='list.image' :alt='list.desc'>
          </a>
        </li>
      </transition-group>
      <div class='carousel-items'>
        <span v-for="(item, index) in slideList.length" :class="{'active':index===currentIndex}" @mouseover="change(index)">{{index}}</span>
      </div>
    </div>
  </body>
  <script src="./vue.js"></script>
  <script type="text/javascript">
    new Vue({
      el: '#carousel',
      data: {
        slideList: [
          {
            'href': '',
            'desc': '1111',
            'image': 'http://img.alicdn.com/tfs/TB1vHswQVXXXXXMXFXXXXXXXXXX-520-280.png_q90_.webp'
          },
          {
            'href': '',
            'desc': '2222',
            'image': 'http://img.alicdn.com/tfs/TB1c9kFQVXXXXcoXpXXXXXXXXXX-520-280.jpg_q90_.webp'
          },
          {
            'href': '',
            'desc': '3333',
            'image': 'https://aecpm.alicdn.com/tps/i1/TB1r4h8JXXXXXXoXXXXvKyzTVXX-520-280.jpg'
          }
        ],
        currentIndex: 0,
        timer: ''
      },
      methods: {
        create: function() {
          var self = this;
          // DOM加載完成後,下個tick中開始輪播
          this.$nextTick(function(){
            self.timer = setInterval(function(){
              self.autoPlay();
            }, 4000)
          })
        },
        go: function() {
          var self = this;
          self.timer = setInterval(function(){
            self.autoPlay();
          },4000)
        },
        stop: function() {
          var self = this;
          clearInterval(self.timer);
          self.timer = null;
        },
        change: function(index) {
          this.currentIndex = index;
        },
        autoPlay: function() {
          this.currentIndex++;
          if(this.currentIndex > this.slideList.length - 1) {
            this.currentIndex = 0;
          }
        }
      }
    })
  </script>
</html>

查看效果 

相關文章
相關標籤/搜索