22vue学习——钩子函数实现半场动画
前言
在前面的两篇文章中我们学习了 vue 中两种实现动画的方法——过渡类名和第三方类。这两种方法实现的动画都是同时实现了入场和离场这两个半场动画的,即实现了整个动画,但是有的时候我们只需要他实现其中的一个离场或者其中的一个入场动画(如将商品加入购物车的过程),前面学到的两种方式就不适用了。那我们该怎么办呢?我们就需要钩子函数来帮助我们了。
可以实现半场动画的钩子函数
1.入场的钩子函数
(1)v-on:before-enter=“beforeEnter”——进入之前
(2)v-on:enter=“enter”——进入
(3)v-on:after-enter=“afterEnter”——进入之后
(4)v-on:enter-cancelled=“enterCancelled”——取消进入2.离场场的钩子函数
(1)v-on:before-leave=“beforeLeave”——离开之前
(2)v-on:leave=“leave”——离开
(3)v-on:after-leave=“afterLeave”——离开之后
(4)v-on:leave-cancelled=“leaveCancelled”——取消离开3.使用了半场动画的钩子函数我们需要在methods 中定义对应的函数,因为我们只需要实现半场动画,所以我们只需要实现进入和离开对应的四个函数即可,其中 enterCancelled 和 leaveCancelled 函数基本没有用到,所以只需要实现其中的三个即可。
使用动画钩子函数的步骤
(1)我们需要将动画作用的那个元素使用 transition 元素包裹起来然后给 transition 绑定三个事件——before-enter enter 和after-enter
(2)在 vue 实例中的 methods 定义相应的函数 beforeEnter enter 和 afterEnter 函数
注意:每一个动画的钩子函数的第一个参数都是 el:表示执行动画的那个 DOM 元素,是一个原生的 js 对象。可以理解为 el 是 通过 Document.getElementById() 来获取的原生 js 对象
其中:
(1)beforeEnter函数:beforeEnter 表示动画入场之前,此时动画还未开始,可以在 beforeEnter中设置元素开始动画之前的起始样式
(2)enter函数: (2.1)beforeEnter 表示动画入场之前,此时动画还未开始,可以在 beforeEnter中设置元素开始动画之前的起始样式
(2.2)el.offsetWidth语句的作用:这个语句没有实际的作用,但是如果不写的话就无法出现动画的效果,可以认为
el.offsetWidth 会强制动画刷新(el.offsetHeight/Left/Right/Top 等也同样有效)
(2.3)done函数的调用:这里的 done 其实就是我们的 afterEnter 函数,也就是说 done 是 afterEnter
函数的引用。如果没有调用 done 的话,会造成 afterEnter 的延迟
(3)afterEnter函数:动画结束之后调用
实现加入购物车效果的总代码
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>钩子函数实现半场动画</title>
<style>
.ball {
width: 15px;
height: 15px;
border-radius: 50%;
background-color: #f00;
}
</style>
</head>
<body>
<div class="body">
<input type="button" value="加入购物车" @click="flag=!flag">
<transition @before-enter="beforeEnter" @enter="enter" @after-enter="afterEnter">
<div class="ball" v-show="flag"></div>
</transition>
</div>
<script src="../lib/vue-2.4.0.js"></script>
<script>
let vm = new Vue({
el: ".body",
data: {
flag: false,
},
// ...
methods: {
beforeEnter(el) {
// 设置小球开始动画之前的起始位置
el.style.transform = "translate(0,0)"
},
enter(el,done) {
el.offsetWidth;
/* 动画结束时小球的状态 */
el.style.transform = "translate(150px,450px)"
/* 动画改变的属性,动画持续的时间,动画的改变效果 */
el.style.transition = "all 1s ease"
done()
},
afterEnter(el) {
// 只是这样的话小球会等一小段时间之后才消失
this.flag = !this.flag
}
})
</script>
</body>
</html>