搭配标签消失/出现(v-show、v-if)的淡入淡出效果
(1)避免动画消失元素恢复原样
因为动画会消失,所以配合js触发动画时改变元素样式到和动画最后一帧相同,就能避免动画消失后元素恢复原样
(2)添加动画模式
自定义动画加载方式,还可以避免视图重绘出现动画混乱
...
在transition标签上添加 mode='out-in / in-out'
out-in:当前元素过渡,过度完后新元素过渡进入
in-out:新元素过渡,过度完成后当前元素过渡离开
(2.5)设置动画过渡时间:
...
:duration="1000" 设置入场/出场动画都为1秒
:duration="{ enter: 500, leave: 800 }" 分别设置入场/出场动画时间
(2.6)设置首屏加载动画:
无论是appear还是@appear钩子都会生成初始渲染过渡
...
(2.7)监听动画/过渡结束
transitionend:监听过渡
animationend:监听animation帧动画
若同一个元素同时使用了以上动画,比如animation很快的被触发并完成了,而transition效果还没结束
type='animation'或'transition',来明确声明需要Vue监听的类型。
1、设置单个组件动画
(1)在要过渡的标签外层包裹
(4)过渡钩子
...
beforeEnter:function (el) {},
enter:function (el, done) {
(1)当与CSS结合使用时,回调函数done是可选的
(2)当只用JavaScript过渡的时候,在enter和leave中必须使用done进行回调
(3)推荐对于仅使用JavaScript过渡的元素添加:css="false",Vue会跳过CSS的检测,这也可以避免过渡过程中 CSS 的影响。
done();
},
afterEnter:function (el) {},
enterCancelled:function (el) {},
beforeLeave:function (el) {},
leave:function (el, done) {
(1)当与CSS结合使用时,回调函数done是可选的
(2)当只用JavaScript过渡的时候,在enter和leave中必须使用done进行回调
(3)推荐对于仅使用JavaScript过渡的元素添加:css="false",Vue会跳过CSS的检测,这也可以避免过渡过程中 CSS 的影响。
done();
},
afterLeave:function (el) {},
leaveCancelled:function (el) {}
2、过渡相同标签切换设置key来区分
当有相同标签名的元素切换时,需要通过key设置唯一的值来标记以让Vue区分它们,否则为了效率只会替换相同标签内部的内容,即使在技术上没有必要,给在组件中的多个元素设置key是一个更好的实践。
3、列表过渡
(1)效果:同时渲染整个列表,且列表的每个元素都具有动画
(2)和transition区别:
不同于 ,它会以一个真实元素呈现:默认为一个 ,指定tag更换为其他元素。
过渡模式mode不可用,因为我们不再相互切换特有的元素。
内部元素总是需要提供唯一的key值。
CSS过渡的类将会应用在内部的元素中,而不是这个组/容器本身。
(3)钩子函数、过渡css、自定义类名、首屏加载和相同
示例:
{
{xx}}
(4)增删元素时,其他元素具有位移过渡
Vue内部使用了一个叫FLIP简单的动画队列,指定transition:transform即可开启过渡
方式一:
...
在css中:
设置了name:x-move{...}
未设置name:v-move{...}
方式二:
...
代码示例:
组件:
<template>
<div>
<button @click='toggle'>toggle</button>
<transition
name="custom-classes-transition"
enter-active-class="animated tada"
leave-active-class="animated bounceOutRight"
>
<p class='box' v-show='show'>hello2</p>
</transition>
</div>
</template>
<script>
export default{
name:'c',
data()
{
return{
show:true
}
},
methods:{
toggle()
{
this.show=!this.show
}
}
}
</script>
<style lang='css' scoped>
.box{
width:100px;
height:100px;
border:solid 1px red;
}
/*.fade-enter,.fade-leave-to{
opacity:0;
width:0;
}
.fade-enter-to,.fade-leave{
opacity:1;
width:100px;
}
.fade-enter-active,.fade-leave-active{
transition:all 3s
}*/
/*.fade-enter-active {
animation: bounce-in .5s;
}
.fade-leave-active {
animation: bounce-in .5s reverse; reverse表示消失时,反过来执行动画
}
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}*/
</style>
变大变小效果:
.fade-enter,.fade-leave-to{
opacity:0;
width:0;
}
.fade-enter-to,.fade-leave{
opacity:1;
width:100px;
}
.fade-enter-active,.fade-leave-active{
transition:all 3s
}
搭配css的animation实现动画效果:
如在进入和过程中缩放:
.x-enter-active {
animation: bounce-in .5s;
}
.x-leave-active {
animation: bounce-in .5s reverse; /*reverse表示消失时,反过来执行动画*/
}
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
搭配第三方库,如swiper的animate.css库实现动画效果:
<transition
name="custom-classes-transition"
enter-active-class="animated x"
leave-active-class="animated xx"
>
<p class='box' v-show='show'>hello2</p>
</transition>
设置页面加载后的入场动画:
<transition
appear
appear-class="custom-appear-class"
appear-to-class="custom-appear-to-class" (2.1.8+)
appear-active-class="custom-appear-active-class"
>
</transition>
列表的交错过渡:
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
<div id="staggered-list-demo">
<input v-model="query">
<transition-group
name="staggered-fade"
tag="ul"
v-bind:css="false"
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:leave="leave"
>
<li
v-for="(item, index) in computedList"
v-bind:key="item.msg"
v-bind:data-index="index"
>{
{
item.msg }}</li>
</transition-group>
</div>
new Vue({
el: '#staggered-list-demo',
data: {
query: '',
list: [
{
msg: 'Bruce Lee' },
{
msg: 'Jackie Chan' },
{
msg: 'Chuck Norris' },
{
msg: 'Jet Li' },
{
msg: 'Kung Fury' }
]
},
computed: {
computedList: function () {
var vm = this
return this.list.filter(function (item) {
return item.msg.toLowerCase().indexOf(vm.query.toLowerCase()) !== -1
})
}
},
methods: {
beforeEnter: function (el) {
el.style.opacity = 0
el.style.height = 0
},
enter: function (el, done) {
var delay = el.dataset.index * 150
setTimeout(function () {
Velocity(
el,
{
opacity: 1, height: '1.6em' },
{
complete: done }
)
}, delay)
},
leave: function (el, done) {
var delay = el.dataset.index * 150
setTimeout(function () {
Velocity(
el,
{
opacity: 0, height: 0 },
{
complete: done }
)
}, delay)
}
}
})