css动画
transition 过渡动画
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>vue中的css动画原理</title>
<script src="../vue.js"></script>
<style>
.fade-enter,
.fade-leave-to {
opacity: 0;
}
.fade-enter-active,
.fade-leave-active {
transition: opacity 1s;
}
</style>
</head>
<body>
<div id="root">
<!-- transition标签包裹 实现组件过渡动画效果 -->
<transition name="fade">
<!-- <child v-if="show"></child> -->
<child v-show="show"></child>
</transition>
<button @click="change">toggle</button>
</div>
<script>
Vue.component("child", {
template: `<div>child</div>`
})
var vm = new Vue({
el: "#root",
data: {
show: true
},
methods: {
change: function() {
this.show = !this.show
}
}
})
</script>
</body>
</html>
通过@keyframes实现
<style>
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
.fade-enter-active{
transform-origin: left center;
animation: bounce-in 1s;
}
.fade-leave-active {
transform-origin: left center;
animation: bounce-in 1s reverse;
}
</style>
animate.css库
通过animate.css库 取代@keyframes
- animate.css官网 daneden.github.io/animate.css… npm install animate.css --save安装
- 头部引入 animate.css库 或
- 注意:需要使用自定义class名使用动画,如 enter-active-class="animated swing" 其中'animated'为必须,后面跟要实现的动画效果名


<body>
<div id="root">
<!-- transition标签包裹 实现组件过渡动画效果 -->
<transition name="fade" enter-active-class="animated swing"
leave-active-class="animated shake">
<!-- <child v-if="show"></child> -->
<child v-show="show"></child>
</transition>
<button @click="change">toggle</button>
</div>
<script>
Vue.component("child", {
template: `<div>child</div>`
})
var vm = new Vue({
el: "#root",
data: {
show: true
},
methods: {
change: function () {
this.show = !this.show
}
}
})
</script>
</body>
vue中同时使用过渡和动画
- 解决上面代码第一次显示没有动画的问题:transition标签加上自定义入场动画名appear。

- 同时实现动画和过渡效果:由于animate.css给定的动画时长是1s,opacity时长是3s,需要设置type="opacity",来使得动画播放时长以opacity时长3s为准。
还需style标签中加入以下样式
.fade-enter, .fade-leave-to {
opacity: 0;
}
.fade-enter-active, .fade-leave-active {
transition: opacity 3s;
}
- 还可自定义动画播放时长:transition标签加上:duration属性(:duration="{enter:2000, leave: 5000}")入场时间为2s,隐藏时间为3s
js动画
vue中的js动画与velocity.js的结合
- 动画钩子@before-enter="handleBeforeEnter",handleBeforeEnter会在el显示前的一瞬间触发。
<body>
<div id="root">
<transition name="fade" @before-enter="handleBeforeEnter">
<div v-show="show">hello world</div>
</transition>
<button @click="handleClick">toggle</button>
</div>
<script>
var vm = new Vue({
el: "#root",
data: {
show: true
},
methods: {
handleClick: function() {
this.show = !this.show
},
handleBeforeEnter: function(el) { // handleBeforeEnter 会在el(这里指div)显示前的一瞬间触发
// console.log('handleBeforeEnter');
el.style.color = "red"
}
}
})
</script>
</body>
- 动画钩子 @enter="handleEnter",函数handleEnter(el,done),动画开始时执行,接收两个参数,el和回调函数。
<body>
<div id="root">
<transition name="fade" @before-enter="handleBeforeEnter" @enter="handleEnter">
<div v-show="show">hello world</div>
</transition>
<button @click="handleClick">toggle</button>
</div>
<script>
var vm = new Vue({
el: "#root",
data: {
show: false
},
methods: {
handleClick: function() {
this.show = !this.show
},
handleBeforeEnter: function(el) { // handleBeforeEnter 会在el(这里指div)显示前的一瞬间触发
// console.log('handleBeforeEnter');
el.style.color = "red"
},
handleEnter: function(el, done) {
setTimeout(() => {
el.style.color = "green" // el先是显示红色,2s后变为绿色
done(); // 调用done,表示动画执行完毕
},2000);
}
}
})
</script>
</body>
- 动画2中的done() 执行完毕后,紧接着是 动画钩子 @after-enter="handleAfterEnter" ,handleAfterEnter(el)接收一个参数el。
<body>
<div id="root">
<transition name="fade" @before-enter="handleBeforeEnter"
@enter="handleEnter" @after-enter="handleAfterEnter">
<div v-show="show">hello world</div>
</transition>
<button @click="handleClick">toggle</button>
</div>
<script>
var vm = new Vue({
el: "#root",
data: {
show: false
},
methods: {
handleClick: function() {
this.show = !this.show
},
handleBeforeEnter: function(el) { // handleBeforeEnter 会在el(这里指div)显示前的一瞬间触发
// console.log('handleBeforeEnter');
el.style.color = "red"
},
handleEnter: function(el, done) {
setTimeout(() => {
el.style.color = "green" // el先是显示红色,2s后变为绿色
},2000);
setTimeout(() => {
done() // 4s的时候绿色执行完
},4000);
},
handleAfterEnter: function(el) { // done() 执行完毕后后执行
el.style.color = "#000" // el开始显示红色,2s后变为绿色,再过2s后变为黑色
}
}
})
</script>
</body>
- 离开的动画钩子,@before-leave @leave @after-leave与enter进入的动画钩子同理,用法一致。
velocity.js 需要引入velocity.js, 用法简单,简单的代码可以完成复杂动画效果。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>vue中的js动画与velocity.js的结合</title>
<script src="../vue.js"></script>
<script src="./velocity.js"></script>
</head>
<body>
<div id="root">
<transition name="fade" @before-enter="handleBeforeEnter" @enter="handleEnter" @after-enter="handleAfterEnter">
<div v-show="show">hello world</div>
</transition>
<button @click="handleClick">toggle</button>
</div>
<script>
var vm = new Vue({
el: "#root",
data: {
show: false
},
methods: {
handleClick: function () {
this.show = !this.show
},
handleBeforeEnter: function (el) {
el.style.opacity = 0
},
handleEnter: function (el, done) {
Velocity(el, {opacity:1}, {duration: 1000, complete: done})
// opacity 由0到1,过渡时间1s,动画执行完done告知,然后控制台打印‘动画执行完毕’
},
handleAfterEnter: function (el) {
console.log('动画执行完毕');
}
}
})
</script>
</body>
</html>
多个元素或组件的过渡
多个元素过渡动画
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>多元素动画过渡</title>
<script src="../vue.js"></script>
<style>
.v-enter, .v-leave-to {
opacity: 0;
}
.v-enter-active, .v-leave-active {
transition: opacity 1s;
}
</style>
</head>
<body>
<div id="root">
<!-- mode="out-in" 控制两个div显示隐藏顺序,out-in表示一个隐藏后另一个再显示。反之in-out同理 -->
<transition mode="out-in">
<div v-if="show" key="hello">hello world</div>
<div v-else key="bye">bye</div>
</transition>
<button @click="handleClick">toggle</button>
</div>
<script>
var vm = new Vue({
el: "#root",
data: {
show: true
},
methods: {
handleClick: function () {
this.show = !this.show
}
}
})
</script>
</body>
</html>
多个组件过渡动画
借助component动态组件来实现两个组件的切换,
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>多元素动画过渡</title>
<script src="../vue.js"></script>
<style>
.v-enter, .v-leave-to {
opacity: 0;
}
.v-enter-active, .v-leave-active {
transition: opacity 1s;
}
</style>
</head>
<body>
<div id="root">
<!-- mode="out-in" 控制两个div显示隐藏顺序,out-in表示一个隐藏后另一个再显示。反之in-out同理 -->
<transition mode="out-in">
<component :is=type></component>
</transition>
<button @click="handleClick">toggle</button>
</div>
<script>
Vue.component('child-one', {
template:"<div>child-one</div>"
})
Vue.component('child-two', {
template: "<div>child-two</div>"
})
var vm = new Vue({
el: "#root",
data: {
type: 'child-one'
},
methods: {
handleClick: function () {
// this.show = !this.show
this.type = this.type === 'child-one' ? 'child-two' : 'child-one'
// 如果显示的组件是child-one组件,就切换成child-two组件,否则切换child-one组件
}
}
})
</script>
</body>
</html>
vue中的列表过渡
只需在想要设定动画效果的元素外层包裹一层transition-group标签即可,然后需要设置style样式,才会有过渡动画效果。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>列表过渡</title>
<script src="../vue.js"></script>
<style>
.v-enter,
.v-leave-to {
opacity: 0;
}
.v-enter-active,
.v-leave-active {
transition: opacity 1s;
}
</style>
</head>
<body>
<div id="root">
<transition-group>
<div v-for="item of List" :key="item.id">{{item.title}}</div>
</transition-group>
<button @click="handleClick">Add</button>
</div>
<script>
// 点击add按钮 实现增加页面数据效果
var count = 0;
var vm = new Vue({
el: "#root",
data: {
List: []
},
methods: {
handleClick: function () {
this.List.push({
id: count ++,
title: "hello world"
})
}
}
})
</script>
</body>
</html>
动画封装
可以将动画封装在一个组件,使用的时候,直接调用组件即可。
<body>
<div id="root">
<fade :show="show">
<div>hello world</div>
</fade>
<fade :show="show">
<h1>hello world</h1>
</fade>
<button @click="handleClick">toggle</button>
</div>
<script>
Vue.component('fade', {
props: ['show'],
template: `
<transition @befor-enter="handleBeforEnter" @enter="handleEnter">
<slot v-if='show'></slot>
</transition>`,
methods: {
handleBeforEnter: function(el) {
el.style.color = "red"
},
handleEnter: function(el, done) {
setTimeout(() => {
el.style.color = "green";
done()
},2000);
}
}
})
var vm = new Vue({
el: "#root",
data: {
show: false,
},
methods: {
handleClick: function () {
this.show = !this.show
}
}
})
</script>
</body>
这里将动画都写进''fade'组件,需要使用动画的时候,直接调用组件fade即可,十分方便。