vue在插入、更新或者移除DOM时,提供多种不同方式的应用过渡效果。包括以下工具:
a、在css过渡和动画中自动应用class
b、可以配合使用第三方css动画库,如 Animate.css
c、在过渡钩子函数中使用javascript直接操作DOM
d、可以配合使用第三方javascript动画库,如 velocity.js
vue提供了transition的封装组件,下列情形中,可以给任何元素和组件添加进入/离开过渡。
a、条件渲染(使用v-if)
b、条件展示 (使用v-show)
c、动态组件
d、组件根节点
例如:
<style>
.fade-enter-active,.fade-leave-active{
transition: opacity .5s;
}
.fade-enter,.fade-leave-to{
opacity:0
}
</style>
<div id='demo'>
<button v-on:click="show =! show">toggle</button>
<transition name='fade'>
<p v-if='show'>hello</p>
</transition>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
new Vue({
el: '#demo',
data: {
show: true
}
});
</script>
当插入或删除包含在transition组件中的元素时,vue将会做以下处理:
a、自动嗅探目标元素是否应用了css过渡或动画,如果是,在恰当的时机添加/删除css类名
b、如果过渡组件提供了javascript的钩子函数,这些钩子函数会在恰当的时机被调用
c、如果没有找到钩子函数,也没有检测到css过渡或动画,DOM操作(插入/删除)在下一帧中立即执行。
1、过渡的类名
在进入/离开的过渡中,会有6个class切换。
a.v-enter:定义进入过渡的开始状态,在元素被插入之后的下一帧移除
b.v-enter-active:定义进入过渡生效时的状态,在整个进入过渡的阶段中应用,在元素被插入之前生效
在过渡/动画完成之后移除。这个类可以被用来定义进入过渡的时间,延迟和曲线函数。
c.v-enter-to:定义进入过渡的结束状态,在元素被插入之后的下一帧生效(与此同时v-enter被移除),在过渡/动画完成之后移除
d.v-leave:定义离开过渡的开始状态,在离开过度被触发时立刻生效,下一帧被移除
e.v-leave-active:定义离开过渡生效时的状态,在整个离开过渡的阶段中应用,在离开过渡触发时立刻生效,
在过渡/动画完成后移除,这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数
f.v-leave-to:定义离开过渡的结束状态,在离开过渡被处触发后下一帧生效(与此同时v-leave被移除),在过渡/动画完成之后移除
对于这些在过渡中切换的类名来说,如果使用的是一个没有名字的transition,则v-会替换这些类名的默认前缀。
如果transition有name='my-transition' 属性,则v-enter会替换为 my-transition-enter
2、css过渡
<style>
.slide-fade-enter-active {
transition: all .3s ease;
}
.slide-fade-leave-active {
transition: all .8s cubic-bezier(1.0, 0.5, 0.8, 1.0);
}
.slide-fade-enter,
.slide-fade-leave-to{
transform: translateX(10px);
opacity: 0;
}
</style>
<div id='demo'>
<button v-on:click="show =! show">toggle</button>
<transition name="slide-fade">
<p v-if="show">hello</p>
</transition>
</div>
3、css动画
css动画用法同css 过渡,区别是动画中 v-enter 类名在节点插入 DOM 后不会立即删除,而是在animationend 事件触发时删除
<style>
.bounce-enter-active{
animation: bounce-in .8s;
}
.bounce-leave-active{
animation:bounce-in .8s reverse;
}
@keyframes bounce-in{
0%{
transform: scale(0);
}
50%{
transform: scale(1.5)
}
100%{
transform:scale(1)
}
}
</style>
<div id='demo'>
<button v-on:click="show =! show">toggle</button>
<transition name="bounce">
<p v-if="show">hello</p>
</transition>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
new Vue({
el: '#demo',
data: {
show: true
}
});
</script>
4、自定义过渡的类名
可以通过以下特性来自定义过渡类名:
a. enter-class
b. enter-active-class
c.enter-to-class
d.leave-class
e.leave-active-class
f.leave-to-class
他们的优先级高于普通的类名,这对于vue的过渡系统和其他第三方css动画库,如animate结合使用十分有用。例如
<link href="https://cdn.jsdelivr.net/npm/[email protected]" rel="stylesheet" type="text/css">
<div id="example">
<button @click="show = !show">
Toggle render
</button>
<transition
name="custom-classes-transition"
enter-active-class="animated tada"
leave-active-class="animated bounceOutRight">
<p v-if="show">hello</p>
</transition>
</div>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
new Vue({
el: '#example',
data: {
show: true
}
})
</script>
5、同时使用过渡和动画
vue为了知道过渡的完成,必须设置相应的事件监听器,它可以是transition 或者 animateionend,这取决于给元素应用的css规则。如果使用其中的任何一种,vue能自动识别类型并设置监听。
在一些场景中,需要给同一个元素同时设置两种过渡效果,比如:animation很快的触发并完成了。而transition效果还没结束。
这种情况中,需要使用type特性并设置animation 或 transition来明确声明需要vue监听的类型
6、显性的过渡持续时间
设置transition 组件上的duration属性定制一个显性的过渡持续时间(以毫米记)
<transition :duration="1000">...</transition>
// 可以定制进入和移出的持续时间
<transition :duration='{enter: 500,leave:800}'>...</transition>
7、Javascript 钩子
可以在属性中声明 javascript钩子
script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/vue.js"></script>
<script>
new Vue({
el: '#example',
data: {
show: false
},
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>
当只用 Javascript 过渡的时候,在 enter 和 leave中,回调函数 done 是必须的。否则,他们会被同步调用,过渡会立即完成。
推荐对于仅使用 Javascript 过渡的元素添加 v-bind:css="false" , vue会跳过css的检测,
这也可以避免过渡过程中css的影响。