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过渡优先级高。

相关文章
相关标签/搜索