Vue.js 提供很是简单的过渡动画接口。这些过渡动画在 Vue.js 将目标元素插入或移除出 DOM 的时候会自动执行。可以触发动画的指令包括 v-if
, v-show
和 v-repeat
。同时,vm 实例的 $appendTo()
, $before()
, $after()
和 $remove()
方法也会触发动画。javascript
定义动画的方法有三种:php
要使用 CSS Transition 动画,只须要在目标元素上添加 v-transition
指令:css
<p class="msg" v-if="show" v-transition>Hello!</p>
而后,你须要为目标元素定义两个 CSS 类: .v-enter
和 .v-leave
. 这其中:html
.v-enter
表明元素刚刚被插入 DOM 瞬间的状态。它会在插入前被添加,而后 Vue.js 会强制浏览器刷新视图,而后 v-enter
会被马上移除,从而触发 transition。.v-leave
表明元素即将被从 DOM 中移除的瞬间的状态。Vue.js 会在侦听到 transitionend
事件之后移除它。须要注意的是你得确保该元素在添加这两个类的时候会触发 CSS transition,否则 Vue.js 侦听不到 transitionend
事件,动画就卡在那里了。vue
.msg { transition: all .3s ease; height: 30px; padding: 10px; background-color: #eee; overflow: hidden; } .msg.v-enter, .msg.v-leave { height: 0; padding: 0 10px; opacity: 0; }
如今,当 show
变化的时候,Vue.js 会插入/移除该元素,并自动在合适的时候添加 CSS 类。java
CSS Animation 使用方式和 transition 大同小异,换成使用 v-animation
指令,不一样的地方是 v-enter
如今不是在插入后马上移除,而是在侦听到 animationend
事件后才移除。git
<p class="animated" v-if="show" v-animation>Look at me!</p>
CSS 里你须要定义两个动画 keyframes,分别对应进场和出场动画:(这里省略了webkit前缀)github
.animated { display: inline-block; } .animated.v-enter { animation: fadein .5s; } .animated.v-leave { animation: fadeout .5s; } @keyframes fadein { 0% { transform: scale(0); } 50% { transform: scale(1.5); } 100% { transform: scale(1); } } @keyframes fadeout { 0% { transform: scale(1); } 50% { transform: scale(1.5); } 100% { transform: scale(0); } }
JS 函数动画须要经过 Vue.effect
方法来注册一个效果,包括一个进场函数和一个出场函数:web
Vue.effect('my-effect', { enter: function (el, insert, timeout) { // insert() 会将元素插入 DOM }, leave: function (el, remove, timeout) { // remove() 会将元素移除出 DOM } })
<p v-effect="my-effect"></p>
第三个参数 timeout
是一个 Vue.js 版本的 setTimeout
函数。使用方法彻底同样,但使用这个函数的好处是,当一个元素的状态切换过快,上一个动画函数设置的 timer 尚未触发就进入下一个动画函数的时候, Vue.js 会确保以前未触发的 timer 都被取消,不须要开发者手动管理 timer。
vue-router
<router-view>
是基本的动态组件,因此咱们能够用 <transition>
组件给它添加一些过渡效果:
<transition> <router-view></router-view> </transition>
<transition>
的全部功能 在这里一样适用。
上面的用法会给全部路由设置同样的过渡效果,若是你想让每一个路由组件有各自的过渡效果,能够在各路由组件内使用 <transition>
并设置不一样的 name。
const Foo = { template: ` <transition name="slide"> <div class="foo">...</div> </transition> ` } const Bar = { template: ` <transition name="fade"> <div class="bar">...</div> </transition> ` }
还能够基于当前路由与目标路由的变化关系,动态设置过渡效果:
<!-- 使用动态的 transition name --> <transition :name="transitionName"> <router-view></router-view> </transition>
// 接着在父组件内 // watch $route 决定使用哪一种过渡 watch: { '$route' (to, from) { const toDepth = to.path.split('/').length const fromDepth = from.path.split('/').length this.transitionName = toDepth < fromDepth ? 'slide-right' : 'slide-left' } }
查看完整例子 这里.