Vue中的动画
为什么
动画能够提高用户的体验,帮助用户更好的理解页面中的功能。
概述
Vue 在插入、更新或者移除 DOM 时,提供多种不同方式的应用过渡效果。
包括以下工具:
- 在 CSS 过渡和动画中自动应用 class
- 可以配合使用第三方 CSS 动画库,如 Animate.css
- 在过渡钩子函数中使用 JavaScript 直接操作 DOM
- 可以配合使用第三方 JavaScript 动画库,如 Velocity.js
使用过渡的类名
- HTML 结构
<div id="app">
<input type="button" value="动起来" @click="myAnimate">
<transition name="fade">
<div v-show="isshow">动画哦</div>
</transition>
</div>
- 使用
transition
将需要过渡的元素包裹起来transition
未设置name属性,style的前缀为v-
;设置后,属性值则为前缀
- VM 实例
// 创建 Vue 实例,得到 ViewModel
var vm = new Vue({
el: '#app',
data: {
isshow: false
},
methods: {
myAnimate() {
this.isshow = !this.isshow;
}
}
});
- 定义两组类样式:
/* 定义进入和离开时候的过渡状态 */
.fade-enter-active,
.fade-leave-active {
transition: all 0.2s ease;
position: absolute;
}
/* 定义进入过渡的开始状态 和 离开过渡的结束状态 */
.fade-enter,
.fade-leave-to {
opacity: 0;
transform: translateX(100px);
}
使用第三方 CSS 动画库
相关属性来自定义过渡类名:
enter-class
enter-active-class
enter-to-class
leave-class
leave-active-class
leave-to-class
他们的优先级高于普通的类名,有利于Vue的过渡系统和其他第三方CSS动画库
- 导入动画类库
animate
:
<link rel="stylesheet" type="text/css" href="./lib/animate.css">
- 定义transition及属性
<transition
enter-active-class="fadeInRight"
leave-active-class="fadeOutRight"
:duration="{ enter: 500, leave: 800 }">
<div class="animated" v-show="isshow">动画哦</div>
</transition>
- 使用
:duration="{ enter : 200, leave: 400 }"
来决定上下半场动画时间- 在使用
animate.css
时,需要在过度类名值前添加animated
,或在transition的子元素内添加class为animated
使用动画钩子函数
以上动画只能实现整场动画,使用动画钩子函数可以实现半场动画。
JS钩子如下:
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"
v-on:enter-cancelled="enterCancelled"
v-on:before-leave="beforeLeave"
v-on:leave="leave"
v-on:after-leave="afterLeave"
v-on:leave-cancelled="leaveCancelled"
>
- before-enter表示动画入场之前,此时动画尚未开始,可以 在 beforeEnter 中,设置元素开始动画之前的起始样式
- enter 表示动画 开始之后的样式,这里,可以设置元素完成动画之后的,结束状态
- 动画完成之后,会调用 after-enter
- 定义
transition
组件以及三个钩子函数
<div id="app">
<input type="button" value="切换动画" @click="isshow = !isshow">
<transition
@before-enter="beforeEnter"
@enter="enter"
@after-enter="afterEnter">
<div v-if="isshow" class="show">OK</div>
</transition>
</div>
- 定义三个 methods 钩子方法:
methods: {
beforeEnter(el) { // 动画进入之前的回调
el.style.transform = 'translateX(500px)';
},
enter(el, done) { // 动画进入完成时候的回调
el.offsetWidth;
el.style.transform = 'translateX(0px)';
done();
},
afterEnter(el) { // 动画进入完成之后的回调
this.isshow = !this.isshow;
}
}
- 注意1:动画钩子函数的第一个参数:el 表示要执行动画的那个参数
- 注意2:
el.offsetWidth;
没有实际的作用,但是,如果不写,出不来动画效果,可以认为 el.offsetWidth 会强制动画刷新。 - 注意3: enter(el, done)这里的 done, 起始就是 afterEnter 这个函数,也就是说:done 是 afterEnter 函数的引用
- 当只用 JavaScript 过渡的时候,在 enter 和 leave 中必须使用 done 进行回调。否则,它们将被同步调用,过渡会立即完成。
推荐对于仅使用 JavaScript 过渡的元素添加 v-bind:css=“false”,Vue 会跳过 CSS 的检测。这也可以避免过渡过程中 CSS 的影响。
- 定义动画过渡时长和样式:
.show{
transition: all 0.4s ease;
}
使用第三方JavaScript动画库
- HTML结构
<script src="https://cdnjs.cloudflare.com/ajax/libs/velocity/1.2.3/velocity.min.js"></script>
<div id="example-4">
<button @click="show = !show">
Toggle
</button>
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:leave="leave"
v-bind:css="false"
>
<p v-if="show">
Demo
</p>
</transition>
</div>
- .定义三个 methods 钩子方法:
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 })
}
}
初始渲染的动画
可以通过 appear
attribute 设置节点在初始渲染的过渡
<transition appear>
<!-- ... -->
</transition>