过渡 & 动画
- 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>