一,css动画原理
1,代码测试
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>css动画原理</title>
<script src="vue.js"></script>
<style type="text/css">
/*.v-enter{
opacity: 0;//从隐藏到显示的开始时
}
.v-enter-active{
transition: opacity 3s;
}
.v-leave-to{
opacity: 0;//从显示到隐藏的结束时
}
.v-leave-active{
transition: opacity 3s;
}*/
.v-enter,
.v-leave-to{
opacity: 0;
}
.v-enter-active,
.v-leave-active{
transition: opacity 3s;
}
</style>
</head>
<body>
<div id="root">
<transition >
<div v-if="show">hello world</div>
</transition>
<button @click="handleClick">切换</button>
</div>
<!-- -->
<script>
var vm = new Vue({
el:'#root',
data:{
show:true
},
methods:{
handleClick:function(){
this.show = !this.show
}
}
})
</script>
</body>
</html>
2,总结
- transition标签定义动画
- v-enter从隐藏到显示的开始时创建,开始后销毁。紧接着,v-enter-to创建,到结束时销毁
- v-leave从显示到隐藏的开始时创建,开始后销毁。紧接着,v-leave-to创建,到结束时销毁
- v-enter-active标签存在于整个动画过程中
- 图示
二,使用animate.css库
1,代码测试
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--https://daneden.github.io/animate.css/-->
<title>vue中使用animate.css库</title>
<script src="vue.js"></script>
<link rel="stylesheet" type="text/css" href="animate.css"/>
<style type="text/css">
@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;
}*/
.active{
transform-origin: left center;
animation: bounce-in 1s;
}
.leave{
transform-origin: left center;
animation: bounce-in 1s reverse;
}
</style>
</head>
<body>
<div id="root">
<!--固定样式-->
<!--<transition name="fade">
<div v-if="show">hello world</div>
</transition>-->
<!--也可以自定义样式名字-->
<!--<transition
name="fade"
enter-active-class = "active"
leave-active-class = "leave"
>
<div v-if="show">hello world</div>
</transition>-->
<!--也可以自定义样式名字,用animate.css的动画-->
<transition
name="fade"
enter-active-class = "animated swing"
leave-active-class = "animated shake"
>
<div v-if="show">hello world</div>
</transition>
<button @click="handleClick">切换</button>
</div>
<!-- -->
<script>
var vm = new Vue({
el:'#root',
data:{
show:true
},
methods:{
handleClick:function(){
this.show = !this.show
}
}
})
</script>
</body>
</html>
2,总结
- 固定样式,要写明transition的name,用固定的css样式fade-enter-active等
- 自定义样式,要用enter-active-class等属性,加入自定义的样式active
- 自定义样式用animate.css的动画,引入animate.css文件,要用enter-active-class等属性,加入animated,再加入添加的动画swing
三,同时使用transition过渡动画和@keyframes css3动画(animate.css)
1,代码测试
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--https://daneden.github.io/animate.css/-->
<title>vue中同时使用transition过渡动画和@keyframes css3动画(animate.css)</title>
<script src="vue.js"></script>
<link rel="stylesheet" type="text/css" href="animate.css"/>
<style>
.fade-enter,.fade-leave-to{
opacity: 0;
}
.fade-enter-active,
.fade-leave-active{
transition: opacity 3s;
}
</style>
</head>
<body>
<div id="root">
<!--appear-active-class 首次出现的动画-->
<!--animate.css 动画都是1s 看源码-->
<!--type="transition" 就会以过渡动画的时间为准3s-->
<!--:duration="10000" 自定义动画时间-->
<!--:duration="{enter:5000, leave:10000}" 进入离开时间分别设置-->
<transition
:duration="{enter:5000, leave:10000}"
name="fade"
appear
enter-active-class = "animated swing fade-enter-active"
leave-active-class = "animated shake fade-leave-active"
appear-active-class= "animated swing"
>
<div v-if="show">hello world</div>
</transition>
<button @click="handleClick">切换</button>
</div>
<!-- -->
<script>
var vm = new Vue({
el:'#root',
data:{
show:true
},
methods:{
handleClick:function(){
this.show = !this.show
}
}
})
</script>
</body>
</html>
2,总结
- appear-active-class 首次出现的动画
- animate.css 动画都是1s 看源码
- type=”transition” 就会以过渡动画的时间为准3s
- :duration=”10000” 自定义动画时间
- :duration=”{enter:5000, leave:10000}” 进入离开时间分别设置
四,js动画与velocity.js动画库实现动画
1,代码测试
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<!--http://velocityjs.org/-->
<title>vue中的js动画与velocity.js动画库实现动画</title>
<script src="vue.js"></script>
<script src="velocity.min.js"></script>
</head>
<body>
<div id="root">
<transition
name="fade"
@before-enter="handleBeforeEnter"
@enter="handleEnter"
@after-enter="handleAfterEnter"
>
<div v-if="show">hello world</div>
</transition>
<button @click="handleClick">切换</button>
</div>
<script>
var vm = new Vue({
el:'#root',
data:{
show:true
},
methods:{
handleClick:function(){
this.show = !this.show
},
// handleBeforeEnter: function(el){
// el.style.color = 'red'
// },
// handleEnter:function(el, done){
// setTimeout(() => {
// el.style.color = 'green'
// },2000)
//
// setTimeout(() => {
// done()
// },4000)
// },
// handleAfterEnter: function(el){
// el.style.color = '#000'
// }
handleBeforeEnter: function(el){
el.style.opacity = 0;
},
handleEnter:function(el, done){
Velocity(el, {
opacity: 1
},{
duration: 1000,
complete: done
})
},
handleAfterEnter: function(el){
console.log("动画结束")
}
}
})
</script>
</body>
</html>
- 都要通过调入属性 @before-enter @enter @after-enter 编写前中后的动画效果
五,多个元素或组件的过渡动画
1,代码测试
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue中多个元素或组件的过渡动画</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">
<!--多个dom过渡动画-->
<!--dom复用 导致动画不会出现 加key-->
<!--out-in先隐藏再显示,in-out先显示再隐藏-->
<!--<transition mode="out-in">
<div v-if="show" key="hello">hello world</div>
<div v-else key="world">bye world</div>
</transition>-->
<!--多个组件过渡动画-->
<!--<transition mode="out-in">
<child v-if="show"></child>
<child-one v-else></child-one>
</transition>-->
<!--动态组件过渡动画-->
<transition mode="out-in">
<component :is="type"></component>
</transition>
<button @click="handleClick">切换</button>
</div>
<script>
Vue.component('child',{
template: '<div>child</div>'
})
Vue.component('child-one',{
template: '<div>child-one</div>'
})
var vm = new Vue({
el:'#root',
data:{
show:true,
type:'child'
},
methods:{
handleClick:function(){
this.type = this.type === 'child' ? 'child-one' : 'child'
}
}
})
</script>
</body>
</html>
2,总结
六,列表过渡动画
1,代码测试
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue中的列表过渡</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>相当于每个item都加上transition标签-->
<transition-group>
<div v-for="(item) of list" :key="item.id">
{{item.title}}
</div>
</transition-group>
<button @click="handleClick">add</button>
</div>
<script>
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>
2,总结
<transition-group>
相当于每个item都加上transition标签
七,vue中的动画封装(用css动画和封装js的动画(推荐))
1,代码测试
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>vue中的动画封装(用css动画和封装js的动画(推荐))</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">
<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 @before-enter="handleBeforeEnter"
@enter="handleEnter">
<slot v-if="show"></slot>
</transition>
`,
methods: {
handleBeforeEnter: 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>
</html>
2,总结
- 推荐封装js的动画,css没法封装,只能全局使用