动画有三种:
1.animate类库
2.css过渡(transition组件)(列表动画)
3.js钩子函数(transition组件)
1.animate类库(要下载包:https://daneden.github.io/animate.css/)
CSS 动画用法同 CSS 过渡,区别是在动画中 v-enter
类名在节点插入 DOM 后不会立即删除,而是在 animationend
事件触发时删除。
我们可以通过以下特性来自定义过渡类名:
enter-class
enter-active-class
enter-to-class
(2.1.8+)leave-class
leave-active-class
leave-to-class
(2.1.8+)
他们的优先级高于普通的类名,这对于 Vue 的过渡系统和其他第三方 CSS 动画库,如 Animate.css 结合使用十分有用。
注意:animated不是animate
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<link rel="stylesheet" href="animate.css-master/animate.css">
</head>
<body>
<script src="vue-2.4.0.js"></script>
<div id="app">
<button @click="flag = !flag">Toggle </button>
<!--<transition-->
<!--name="custom-classes-transition"-->
<!--enter-active-class="animated flipIn"-->
<!--leave-active-class="animated bounceOutRight"-->
<!--:duration="{ enter: 200, leave: 800 }">-->
<!--<p v-if="flag">hello</p>-->
<!--</transition>-->
<!--简写方法-->
<transition
name="custom-classes-transition"
enter-active-class=" flipIn"
leave-active-class=" bounceOutRight"
:duration="{ enter: 200, leave: 800 }">
<p v-if="flag"class="animated" >hello</p>
</transition>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
flag:true
},
methods:{
}
})
</script>
</body>
</html>
2.css过渡(transition组件)
过渡的类名
在进入/离开的过渡中,会有 6 个 class 切换。
-
v-enter
:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。 -
v-enter-active
:定义进入过渡生效时的状态。在整个进入过渡的阶段中应用,在元素被插入之前生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。(transition) -
v-enter-to
: 2.1.8版及以上 定义进入过渡的结束状态。在元素被插入之后下一帧生效 (与此同时v-enter
被移除),在过渡/动画完成之后移除。 -
v-leave
: 定义离开过渡的开始状态。在离开过渡被触发时立刻生效,下一帧被移除。 -
v-leave-active
:定义离开过渡生效时的状态。在整个离开过渡的阶段中应用,在离开过渡被触发时立刻生效,在过渡/动画完成之后移除。这个类可以被用来定义离开过渡的过程时间,延迟和曲线函数。(transition)
v-leave-to
: 2.1.8版及以上 定义离开过渡的结束状态。在离开过渡被触发之后下一帧生效 (与此同时 v-leave
被删除),在过渡/动画完成之后移除
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
/*进入的时候*/
.slide-fade-enter-active {
transition:all 0.3s ease;
}
/*离开的时候*/
.slide-fade-leave-active {
transition:all 0.8s ease;
}
.slide-fade-enter, .slide-fade-leave-to{
transform:translateX(160px);
opacity:0;
}
/*进入的时候*/
.v-enter-active {
transition:all 0.3s ease;
}
/*离开的时候*/
.v-leave-active {
transition:all 1s ease;
}
.v-enter, .v-leave-to{
transform:translateX(160px);
opacity:0;
}
</style>
</head>
<body>
<script src="vue-2.4.0.js"></script>
<div id="app">
<button @click="flag = !flag">Toggle </button>
<transition name="slide-fade">
<p v-if="flag">hello</p>
</transition>
<hr>
<!--不给transition name时,默认为v- -->
<button @click="flag1 = !flag1">默认的Toggle </button>
<transition>
<p v-if="flag1">hello</p>
</transition>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
flag:true,
flag1:true
},
methods:{
}
})
</script>
</body>
</html>
列表动画
在dom中transition-group显示为span标签
appear属性:实现页面刚展示出来的时候,入场的效果
tag属性:指定transition-group这个元素在浏览器中渲染为指定的元素,
如果不添加tag属性,那么页面自动将该标签渲染为span标签
v-move
列表的进入/离开过渡,对列表直接操作(增、删)的元素,封装<transition-group>并按常规的CSS或JS过渡即可;但在操作这些元素的位置变化时,由于DOM文档流的变化,会同时引起其它(邻近)节点元素的位置变化,例如在列表插入一个<li>,插入点原本的<li>会下移,删除一个<li>,下面的<li>会上移补充占据这个位置。
对于这些“被动”移动的元素来说,也可以实现过渡,这就用到了v-move 特性。
<div id="app">
<!--appear属性:实现页面刚展示出来的时候,入场的效果
tag属性:指定transition-group这个元素在浏览器中渲染为指定的元素,
如果不添加tag属性,那么页面自动将该标签渲染为span标签-->
<!--<ul>-->
<transition-group appear tag="ul">
<li @click="del(index)" v-for="(item,index) in list" :key="item">{{item}}</li>
</transition-group>
<!--</ul>-->
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
msg:'我要猎杀那些黑暗中的人',
list: [1,2,3,4,5,6,7,8,9]
},
methods:{
del(i){
this.list.splice(i,1);
}
}
})
3.js钩子函数(transition组件)
可以在属性中声明 JavaScript 钩子
<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" > <!-- ... --> </transition>
|
注意:当只用 JavaScript 过渡的时候,在 enter
和 leave
中必须使用 done
进行回调。否则,它们将被同步调用,过渡会立即完成。
推荐对于仅使用 JavaScript 过渡的元素添加 v-bind:css="false"
,Vue 会跳过 CSS 的检测。这也可以避免过渡过程中 CSS 的影响。
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
p{
background-color: red;
display: inline-block;
border-radius: 50%;
}
</style>
</head>
<body>
<script src="vue-2.4.0.js"></script>
<div id="app">
<button @click="flag = !flag">Toggle </button>
<transition
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"
>
<p v-show="flag">hello</p>
</transition>
</div>
<script>
var vm = new Vue({
el:'#app',
data:{
flag:false
},
methods:{
beforeEnter:function (el) {
el.style.transform = 'translateX(0)';
},
enter:function (el,done) { /*当与css结合时 done时可选的*/
el.offsetLeft;
el.style.transform = 'translateX(150px)';
el.style.transition = 'all 2s ease ';
done();
},
afterEnter:function (el) {
this.flag = !this.flag;
// el.style.transform = 'translateX(150px)';
// el.style.transition = 'all 2s ease ';
// opacity = 1;
}
}
})
</script>
</body>
</html>
创建组件:通过 Vue component(‘组件名’,{})
注意一定要以-的形式命名(w3c规则)
Vue。component(‘com-1’{
template:‘’ 注意:<transition>中一定要有一个根元素div
})
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
p{
background-color: red;
display: inline-block;
border-radius: 50%;
}
#template div h1{
color: red;
}
</style>
</head>
<body>
<script src="vue-2.4.0.js"></script>
<div id="app">
<my-com1></my-com1>
<my-com2></my-com2>
<my-com3></my-com3>
<my-com4></my-com4>
<my></my>
</div>
<template id="template">
<div>
<h1 style="color: red"> 这是我通过外部template来创建的组件,不能写外联样式???????</h1>
<h1 style="color: red"> template标签在div外面</h1>
</div>
</template>
<!--//注意组件template里面一定要有标签-->
<template id="template2"><h1>这是私有组件</h1></template>
<script>
// 使用Vue.extend来创建全局组件
var com1 = Vue.extend({
// 通过template属性,指定了组件要展示的html解构
template: '<h1>这是用Vue.extend创建的组件</h1>'
});
Vue.component('my-com1',com1);
Vue.component('my-com2',Vue.extend({
// 通过template属性,指定了组件要展示的html解构
template: '<h2>这是用Vue.extend创建的第二种写法组件</h2>'
}));
Vue.component('my-com3',{
// 通过template属性,指定了组件要展示的html解构
template: '<h3>这是用Vue.extend创建的第3种写法组件</h3>'
});
Vue.component('my-com4',{
// 通过template属性,指定了组件要展示的html解构
template: '<div><h4>这是用Vue.extend创建的第3种写法组件</h4> <h4>这是我在后面加的第二个h4,必须要加根元素</h4></div>'
});
Vue.component('my-com4',{
// 通过template属性,指定了组件要展示的html解构
template: '#template'
});
var vm = new Vue({
el:'#app',
data:{
flag:false
},
methods:{},
components:{
my :{
template: '#template2'
}
}
})
</script>
</body>
</html>
注意:组件定义一个data -----------一定要是方法,且return一个对象
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
p{
background-color: red;
display: inline-block;
border-radius: 50%;
}
</style>
</head>
<body>
<script src="vue-2.4.0.js"></script>
<div id="app">
<login-a></login-a>
</div>
<script>
// 组件中可以由自己的data数据,data必须是方法,且必须返回一个对象,data数据必须只能在template中{{}},不能再app总{{}}
Vue.component('login-a',{
template:'<h3>这是一个全局的简化的组件===={{msg}}</h3>',
data: function () { //必须是方法,且必须返回一个对象
return {msg:'这是我通过我创建的组件来创建的data,它是一个方法,并且返回的是一个对象'}
}
});
var vm = new Vue({
el:'#app',
data:{
flag:false
},
methods:{},
components:{
my :{
template: '#template2'
}
}
})
</script>
</body>
</html>
也可以定义methods(例如创建一个计数组件)
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
p{
background-color: red;
display: inline-block;
border-radius: 50%;
}
</style>
</head>
<body>
<script src="vue-2.4.0.js"></script>
<div id="app">
<counter></counter>
<hr>
<counter></counter>
<hr>
<counter></counter>
<hr>
<counter></counter>
<hr>
<counter></counter>
</div>
<template id="count">
<div>
<button @click="add">+1</button>
<h3>{{count}}</h3>
</div>
</template>
<script>
// 组件中可以由自己的data数据,data必须是方法,且必须返回一个对象,data数据必须只能在template中{{}},不能再app总{{}}
Vue.component('counter',{
template:'#count',
data:function () {
return {count:0} /*这里不能用变量,否则调用的同一个对象*/
},
methods:{
add(){
this.count++;
}
}
});
var vm = new Vue({
el:'#app',
data:{
flag:false
},
methods:{}
})
</script>
</body>
</html>
组件切换(v-if或者component)
<component :is="flag"></component>
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Title</title>
<style>
p{
background-color: red;
display: inline-block;
border-radius: 50%;
}
.v-renter,.v-leave-to{
opacity: 0;
transform: translate(150px);
}
.v-leave-active,.v-enter-active{
transition: all 2s ease;
}
</style>
</head>
<body>
<script src="vue-2.4.0.js"></script>
<div id="app">
<!--<button @click="flag=true">登录</button >-->
<!--<button @click="flag=false">注册</button>-->
<!--<login v-if="flag"></login>-->
<!--<register v-else="flag"></register>-->
<button @click="flag='login'">登录</button >
<button @click="flag='register'">注册</button>
<transition mode="out-in"> <!--如果不添加mode="out-in",那么,点击按钮时切换下一个组件和上一个组件动画同时进行-->
<component :is="flag"></component>
</transition>
</div>
<script>
// 组件中可以由自己的data数据,data必须是方法,且必须返回一个对象,data数据必须只能在template中{{}},不能再app总{{}}
Vue.component('login',{
template:'<h1>登录组件</h1>'
});
Vue.component('register',{
template:'<h1>注册组件</h1>'
});
var vm = new Vue({
el:'#app',
data:{
// flag:true
flag:'login'
},
methods:{}
})
</script>
</body>
</html>