目录
- css transition
- css animation
- 使用js的动画
- 多个元素的过渡
- 多组件的过渡
- 列表过渡
目前vue提供的动画实现方法肯定不止这几种,这次学习了几种比较有用,实现起来方便的进行总结
学习方法
CRM:copy run manage
先从官方文档抄代码,运行出来,最后修改成自己想要的效果
css transition
使用过渡实现动画
实现一个比较简单的淡入淡出效果
首先从vue的官方文档中抄代码
页面结构,我们发现vue的动画内容都需要由一个transition的标签包裹,并且提供name属性
<div id="demo">
<button v-on:click="show = !show">
Toggle
</button>
<transition name="fade">
<p v-if="show">hello</p>
</transition>
</div>
css内容,这里出现了几个新的类,等下我们会去逐个进行研究,但是去掉类看其他代码,不难发现上面的是使用过渡,下面的是定义过渡
.fade-enter-active, .fade-leave-active {
transition: opacity .5s;
}
.fade-enter, .fade-leave-to /* .fade-leave-active below version 2.1.8 */ {
opacity: 0;
}
js内容,很普通的vue结构
new Vue({
el: '#demo',
data: {
show: true
}
})
实现效果:
我们来研究一下这几个类分别代表了什么含义
fade-enter 淡入的第一帧的状态,.fade-enter-active 淡入的过程动画
.fade-enter{
background:red;
opacity: 0;
width:100px;
}
.fade-enter-active{
transition: all 1s;
}
不难发现一开始的状态和fade-enter中定义的css样式是一致的,同时整个淡入过程持续了1s
fade-enter-to 过渡的结束状态,我们再加上这个代码来看看效果
.fade-enter-to{
font-size:40px;
}
我们发现过渡的结束状态和fade-enter-to的样式是一致的,但是最后又回到了原始状态
根据官方文档的解释,过渡结束之后,fade-enter-to fade-enter-active都会删掉
fade-leave方向的三个类和enter是处于相反的状态,就不一一演示了
css animation
使用animation实现动画
CSS 动画用法同 CSS 过渡,区别是在动画中v-enter
类名在节点插入 DOM 后不会立即删除,而是在animationend
事件触发时删除。
第一步,从官网抄代码
结构部分,跟过渡的页面结构没有区别
<div id="example-2">
<button @click="show = !show">Toggle show</button>
<transition name="bounce">
<p v-if="show">Lorem ipsum dolor sit amet, consectetur adipiscing elit. Mauris facilisis enim libero, at lacinia diam fermentum id. Pellentesque habitant morbi tristique senectus et netus.</p>
</transition>
</div>
css部分,从过渡变为了定义css动画,同时在active类中添加动画的引用
.bounce-enter-active {
animation: bounce-in .5s;
}
.bounce-leave-active {
animation: bounce-in .5s reverse;
}
@keyframes bounce-in {
0% {
transform: scale(0);
}
50% {
transform: scale(1.5);
}
100% {
transform: scale(1);
}
}
运行效果
相当于使用动画定义了过渡效果
一般结合animate.css这个动画库来进行使用
<link href="https://cdn.jsdelivr.net/npm/animate.css@3.5.1" rel="stylesheet" type="text/css">
<div id="example-3">
<button @click="show = !show">
Toggle render
</button>
<transition
name="custom-classes-transition"
enter-active-class="animated tada"
leave-active-class="animated bounceOutRight"
>
<p v-if="show">hello</p>
</transition>
</div>
使用动画库,连css都不用写了
使用js的动画
vue对于动画提供了八个钩子
可以在 attribute 中声明 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>
在methods当中可以使用这些钩子
methods: {
// --------
// 进入中
// --------
beforeEnter: function (el) {
// ...
},
// 当与 CSS 结合使用时
// 回调函数 done 是可选的
enter: function (el, done) {
// ...
done()
}
}
也可以使用velocity这个js库,每一个velocity中都包含了一个动画的变化帧
new Vue({
el: '#example-4',
data: {
show: false
},
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 })
}
}
})
实现效果
多个元素的过渡
比如有两个按钮,我们需要在一个按钮滑出的同时另外一个按钮滑入,这样同时有两个元素的过渡效果。
页面结构,和transition相似,但是添加了一个mode属性
in-out
:新元素先进行过渡,完成之后当前元素过渡离开。out-in
:当前元素先进行过渡,完成之后新元素过渡进入。
<div id="example-4">
<transition name='fade' mode="out-in">
<button v-if="status==='off'" key="on" @click='status="on"'>
on
</button>
<button v-else key="off" @click='status="off"'>
off
</button>
</transition>
</div>
css
.fade-enter-active,
.fade-leave-active {
transition:all 1s;
}
.fade-enter{
opacity:0;
background:red;
transform:translateX(100px)
}
.fade-leave-to{
opacity:0;
transform:translateX(-100px);
}
实现效果
多组件过渡
多个组件的过渡简单很多 - 我们不需要使用
key
attribute。相反,我们只需要使用动态组件:
<transition name="component-fade" mode="out-in">
<component v-bind:is="view"></component>
</transition>
使用动态组件 :is
new Vue({
el: '#transition-components-demo',
data: {
view: 'v-a'
},
components: {
'v-a': {
template: '<div>Component A</div>'
},
'v-b': {
template: '<div>Component B</div>'
}
}
})
实现效果
列表过渡
如何同时渲染整个列表的动画效果呢
比如使用v-for
?在这种场景中,使用<transition-group>
组件。
列表的过渡使用了transition-group进行包裹,tag用来指定这个group被替换成什么元素
这里指定被替换为p元素
<div id="list-demo" class="demo">
<button v-on:click="add">Add</button>
<button v-on:click="remove">Remove</button>
<transition-group name="list" tag="p">
<span v-for="item in items" v-bind:key="item" class="list-item">
{{ item }}
</span>
</transition-group>
</div>
css就和前面的动画一样写就好啦
js中写一个生成随机数的函数,然后写两个button的点击事件
new Vue({
el: '#list-demo',
data: {
items: [1,2,3,4,5,6,7,8,9],
nextNum: 10
},
methods: {
randomIndex: function () {
return Math.floor(Math.random() * this.items.length)
},
add: function () {
this.items.splice(this.randomIndex(), 0, this.nextNum++)
},
remove: function () {
this.items.splice(this.randomIndex(), 1)
},
}
})
展示效果
总结
这次一共学习了六种vue中的动画实现方式