过渡 & 动画
- v-enter:定义进入过渡的开始状态。在元素被插入之前生效,在元素被插入之后的下一帧移除。
- v-enter-active:定义进入过渡生效时的状态。可以被用来定义进入过渡的过程时间,延迟和曲线函数。
- v-enter-to: 定义进入过渡的结束状态。
- v-leave: 定义离开过渡的开始状态。
- v-leave-active:定义离开过渡生效时的状态。
- v-leave-to:定义离开过渡的结束状态。
<style>
.section {
width: 200px;
height: 200px;
background: #00ffff;
}
.v-enter {
width: 0px;
background: #00ff00;
}
.v-enter-active {
background:#ff0000;
transition: all 5s linear;
}
.v-enter-to {
background: orange;
}
/* 进入状态结束 变成默认颜色 */
.v-leave {
background: #00ff00;
}
.v-leave-active {
width: 0;
background: rgb(238, 88, 200);
transition: all 5s linear;
}
.v-leave-to {
background: #29013b;
}
/* 离开状态结束 是消失 */
</style>
JS 钩子动画
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
ul{
list-style: none;
margin: 0;
padding: 0;
}
li {
display: flex;
align-items: center;
margin: 20px;
}
li img {
display: block;
width: 150px;
height: 80px;
margin-right: 20px;
}
span {
position: absolute;
width: 150px;
height: 80px;
/* background: #00ffff; */
transition: all 2s linear;
}
.cart {
width: 150px;
height: 50px;
background: #00ff66;
position: fixed;
right: 50px;
bottom: 50px;
line-height: 50px;
text-align: center;
font-size: 25px;
color: #ffffff;
}
</style>
</head>
<body>
<div id="app">
<ul>
<!-- ref= "listArray" 专门用来获取 dom 元素 -->
<li v-for = "(item,index) in lists" :key = `${index}_a` ref= "listArray" >
<img :src="item.cover" alt="">
<button @click = "addCart(index)">加入购物车</button>
</li>
</ul>
<transition @enter = "enter" @after-enter = "after">
<span v-if="isShow"></span>
</transition>
<div class="cart" ref = "cart">购物车</div>
</div>
</body>
</html>
<script src="vue.min.js"></script>
<script>
let vm = new Vue({
el: '#app',
data: {
currentIndex: -1, // 加入购物车的默认索引
isShow: false,
lists: [
{
id: 1,
cover: 'http://www.javascript.cn/203853de0f7a753037.png'
},
{
id: 2,
cover: 'http://www.javascript.cn/202711f70eea987000.jpg'
},
{
id: 3,
cover: 'http://www.javascript.cn/211735f96b30549920.jpg'
}
]
},
methods: {
addCart(index) {
// console.log('加入购物车',index);
this.currentIndex = index
this.isShow = true
// console.log(this.currentIndex);
},
enter(el,done) { // el 表示当前的动画元素 done 表示动画执行完成后的回调函数
// 确定点击元素 li 的位置 ref= "listArray" 专门用来获取 dom 元素
// console.log(this.$refs.listArray,111);
let oLi = this.$refs.listArray[this.currentIndex];
// console.log(oLi,222);
let { x, y } = oLi.getBoundingClientRect();//
// 设置 span 动画元素的位置 与点击元素 li 位置一样
// console.log(x,y);
el.style.left = x + 'px';
el.style.top = y + 'px';
el.style.background = `url(${this.lists[this.currentIndex].cover})`;
el.style.backgroundSize = '100% 100%'
// 求出购物车的位置
let Cart = this.$refs.cart
let {x:a,y:b} = Cart.getBoundingClientRect()// x, y 重新命名 a,b
// 动画元素到购物车移动的距离
el.style.transform = `translate3d(${a - x}px,${b - y}px,0) scale(0)`;
el.addEventListener('transitionend', done, false);
},
after() {
this.isShow = false;
}
}
})
</script>