Vue之Transition淺談

經過Vue.js的過渡系統,在節點插入/移除DOM的過程當中,你能夠輕鬆的運用自動過渡效果。這裏有兩個方式能夠使用過渡系統:javascript

定義帶有過渡效果/動畫的css class,或者註冊一個包含自定義JavaScript鉤子函數的對象。css

經過使用v-transition="my-transition"指令的運用,Vue將會:html

  1. 試着找到一個id爲"my-transition",而且經過Vue.transition(id, def)或通過transitions選項處理的Javascript過渡定義。當找到時,Vue將會使用該定義對象執行自定義的JavaScript過渡。java

  2. 若是沒有找到自定義的Javacript過渡定義,那麼Vue將會自動發現使用了CSS過渡/動畫效果的目標元素,並在適當的時機添加/移除CSS class。web

  3. 若是沒有檢測到過渡/動畫,那麼就會在下一幀直接執行DOM操做markdown

全部的Vue.js過渡效果只會在Vue.js執行DOM操做時纔會被觸發;或者經過內建指令集,例如v-if;或者經過Vue實例方法,例如vm.$appendTo()app

CSS 過渡效果

一個典型的CSS過渡效果定義以下:函數

<p class="msg" v-if="show" v-transition="expand">Hello!</p>
複製代碼

你須要給.expand-enter.expand-leave定義CSS規則:佈局

.msg {
  transition: all .3s ease;
  height: 30px;
  padding: 10px;
  background-color: #eee;
  overflow: hidden;
}
.msg.expand-enter, .msg.expand-leave {
  height: 0;
  padding: 0 10px;
  opacity: 0;
}
複製代碼
<div id="demo"><p class="msg" v-if="show" v-transition="expand">Hello!</p><button v-on="click: show = !show">Toggle</button></div>
複製代碼
<style>
.msg {
  transition: all .5s ease;
  height: 30px;
  background-color: #eee;
  overflow: hidden;
  padding: 10px;
  margin: 0 !important;
}
.msg.expand-enter, .msg.expand-leave {
  height: 0;
  padding: 0 10px;
  opacity: 0;
}
</style>

<script>
new Vue({
  el: '#demo',
  data: { show: true }
})
</script>
複製代碼

這些class根據v-transition指令指定的值進行觸發。在指定v-transition="fade"這個例子中,經過.fade-enter.fade-leave來觸發class變換。當未指定值的時候,則使用默認.v-enter.v-leave動畫

show屬性發生變化,Vue.js依據其變化來插入/移除<p>元素,並使用過渡class,具體以下:

  • show爲false時,Vue.js將會:

    1. v-leave類應用於元素並觸發過渡效果;
    2. 等待過渡效果執行完畢; (經過監聽一個transitionend事件)
    3. 從DOM中移除節點並移除class v-leave.
  • show爲true時,Vue.js將會:

    1. 將classv-enter應用於節點上;
    2. 將節點插入DOM;
    3. 觸發CSS佈局變化,v-enter定義的效果將會被自動應用;
    4. 移除classv-enter,觸發節點過渡效果,回到節點默認狀態。

當多個節點同時觸發過渡效果時,Vue.js將會進行批量處理,只觸發一次佈局修改

CSS 動畫

CSS 動畫經過與CSS過渡效果同樣的方式進行調用,區別就是動畫中v-enter並不會在節點插入DOM後立刻移除,而是在animationend回調中移除

示例: (省略了css前綴的規則)

<p class="animated" v-if="show" v-transition="bounce">Look at me!</p>
複製代碼
.animated {
  display: inline-block;
}
.animated.bounce-enter {
  animation: bounce-in .5s;
}
.animated.bounce-leave {
  animation: bounce-out .5s;
}
@keyframes bounce-in {
  0% {
    transform: scale(0);
  }
  50% {
    transform: scale(1.5);
  }
  100% {
    transform: scale(1);
  }
}
@keyframes bounce-out {
  0% {
    transform: scale(1);
  }
  50% {
    transform: scale(1.5);
  }
  100% {
    transform: scale(0);
  }
}
複製代碼
<div id="anim" class="demo"><span class="animated" v-if="show" v-transition="bounce">Look at me!</span><br><button v-on="click: show = !show">Toggle</button></div>
複製代碼
<style>
  .animated {
    display: inline-block;
  }
  .animated.bounce-enter {
    -webkit-animation: bounce-in .5s;
    animation: bounce-in .5s;
  }
  .animated.bounce-leave {
    -webkit-animation: bounce-out .5s;
    animation: bounce-out .5s;
  }
  @keyframes bounce-in {
    0% {
      transform: scale(0);
      -webkit-transform: scale(0);
    }
    50% {
      transform: scale(1.5);
      -webkit-transform: scale(1.5);
    }
    100% {
      transform: scale(1);
      -webkit-transform: scale(1);
    }
  }
  @keyframes bounce-out {
    0% {
      transform: scale(1);
      -webkit-transform: scale(1);
    }
    50% {
      transform: scale(1.5);
      -webkit-transform: scale(1.5);
    }
    100% {
      transform: scale(0);
      -webkit-transform: scale(0);
    }
  }
  @-webkit-keyframes bounce-in {
    0% {
      -webkit-transform: scale(0);
    }
    50% {
      -webkit-transform: scale(1.5);
    }
    100% {
      -webkit-transform: scale(1);
    }
  }
  @-webkit-keyframes bounce-out {
    0% {
      -webkit-transform: scale(1);
    }
    50% {
      -webkit-transform: scale(1.5);
    }
    100% {
      -webkit-transform: scale(0);
    }
  }
</style>
複製代碼
<script>
new Vue({
  el: '#anim',
  data: { show: true }
})
</script>
複製代碼

Javascript 方法

如下的例子中,使用了jQuery註冊一個自定義Javascript的過渡效果:

Vue.transition('fade', {
  beforeEnter: function (el) {
    // a synchronous function called right before the
    // element is inserted into the document.
    // you can do some pre-styling here to avoid
    // FOC (flash of content).
  },
  enter: function (el, done) {
    // element is already inserted into the DOM
    // call done when animation finishes.
    $(el)
      .css('opacity', 0)
      .animate({ opacity: 1 }, 1000, done)
    // optionally return a "cancel" function
    // to clean up if the animation is cancelled
    return function () {
      $(el).stop()
    }
  },
  leave: function (el, done) {
    // same as enter
    $(el).animate({ opacity: 0 }, 1000, done)
    return function () {
      $(el).stop()
    }
  }
})
複製代碼

以後你就能夠經過給v-transition指定過渡ID來應用。注意,經過Javascript聲明的過渡比CSS過渡優先級高。

相關文章
相關標籤/搜索