transition 必须要加一个 name 属性 不然动画会消失
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
<script src="lib/vue.js"></script>
<style>
.box {
height: 20px;
width: 20px;
background-color: pink;
border-radius: 50%;
}
</style>
</head>
<body>
<div id="app">
<button v-on:click="flag=!flag">点击显示</button>
<transition
name="fade"
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter"
v-on:enter-cancelled="enterCancelled"
>
<div class="box" v-show="flag"></div>
</transition>
</div>
<script>
var app = new Vue({
el: '#app',
data: {
flag: false
},
methods: {
//动画钩子函数的第一个参数指向要执行这动画的元素,是一个原生的js dom对象
//可以理解为通过document,getElementById()获取到的元素
// 第一个函数在动画开始之前执行,可以设置一些动画开始之前的样式
//每次动画开始的时候,都会执行这个函数,所以小球会到远原点
beforeEnter: function (el) {
// 设置小球执行动画之前的其实位置
el.style.transform = "translate(0, 0)"
},
//动画开始之后的状态,可以设置小球开始动画后的结束状态
enter: function (el, done) {
//不写没有动画效果,它实际上没有什么意义,就是强制动画刷新
el.offsetWidth
el.style.transform = "translate(450px, 450px)"
el.style.transition = "all .8s ease"
// 这里的done其实就是afterEnter函数,done是afterEnter函数的引用
// 让动画执行完之后立马执行afterEnter函数
done()
},
// 动画完成之后执行的函数
afterEnter: function (el) {
this.flag = !this.flag
},
enterCancelled: function (el) {}
}
})
</script>
</body>
</html>
应注意的问题:
1. transition 标签中必须加一个 name 属性, 不然 enter 钩子函数会导致动画消失,因为 after-enter 动画提前执行了
<transition name="fade"
v-on:before-enter="beforeEnter"
v-on:enter="enter"
v-on:after-enter="afterEnter">
<div class="ball" v-if="flag"></div>
</transition>
2. 屏幕滑动和分辨率会导致小球每次要移动的距离不一样,所以要计算小球每次要移动的位置
计算方法: domObject.getBoundingClientRect(), 有上下左右四个值
其中页脚的购物车图标位于组件 app 里面,而购物车页面在 GoodsInfo 组件里面,但是只要页面中只要存在这个dom元素,就是可以获取到的,所以只需要在 app 组件里面给购物车图标加一个 id ,在GoodsInfo组件里面直接获取就行了
enter: function (el, done) {
var cart = document.getElementById('badge').getBoundingClientRect()
var ball = document.getElementById('ball').getBoundingClientRect()
var x = cart.left - ball.left
var y = cart.top - ball.top
el.offsetWidth
// 字符串的拼接
el.style.transform = `translate(${x}px, ${y}px)`
// 动画函数
el.style.transition = "all 1s cubic-bezier(0, 0, 0.25, 1)"
done()
}