您的位置:首页 > Web前端 > Vue.js

vue饿了么(五)--购物车小球动画实现

2018-11-05 16:37 966 查看

1.cartcontrol.vue,添加商品时,派发一个事件给goods.vue,获取当前DOM,方便计算小球下落位置。

[code]addCart(event) {
if(!event._constructed) {//非自定义点击事件的情况下return掉,这样pc端就不会检测到两次点击事件。
return;
}
// console.log(this.food.count);
if(!this.food.count){
Vue.set(this.food,'count',1);
//给对象添加他不存在的属性时,这样的方式是不行的。需要用Vue的Vue.set()
// this.food.count=1;
}else{
this.food.count++;
}
this.$emit('cart-add',event.target);//添加商品时,派发一个事件,将当前DOM传递给goods.vue
},

2.goods.vue接收

[code]<div class="cartcontrol-wrapper">
<cartcontrol :food='food' @cart-add="cartAdd"></cartcontrol>
</div>
[code]cartAdd(el) {
//体验优化,异步执行下落动画,画面不容易卡顿。
this.$nextTick(() => {
this.$refs.shopcart.drop(el);
});
},

3.goods.vue中调用子组件shopcart.vue的drop()方法

[code]drop(el) {
// console.log(el);
//遍历小球,找到show为false的小球
for(let i=0;i<this.balls.length;i++){
let ball = this.balls[i];
if(!ball.show) {
ball.show = true;
ball.el = el;//用小球的el对象保留这个element
this.dropBalls.push(ball);
return;
}
}
},
[code]<div class="ball-container"> 
<transition-group name="drop" v-on:before-enter="beforeEnter" v-on:enter="enter" v-on:after-enter="afterEnter">
<div class="ball" v-for="(ball,index) in balls" v-show="ball.show" :key="index">
<div class="inner inner-hook"></div>
</div>
</transition-group>
</div>

钩子函数

[code]beforeEnter: function (el) {
/*el是小球;
遍历所有show为true的小球*/
let count = this.balls.length;
while(count--) {
let ball = this.balls[count];
if(ball.show) {
let rect = ball.el.getBoundingClientRect();//获得该元素(加号)相对于视口的位置的偏移(left,top)
let x = rect.left-32;
let y = -(window.innerHeight-rect.top-22);
el.style.display = '';
el.style.webkitTransform = `translate3d(0,${y}px,0)`;//外层做纵向运动
el.style.transform = `translate3d(0,${y}px,0)`;
let inner = el.getElementsByClassName('inner-hook')[0];
inner.style.webkitTransform = `translate3d(${x}px,0,0)`;
inner.style.transform = `translate3d(${x}px,0,0)`;
}
}
},
enter: function (el) {
let rf = el.offsetHeight;//必须重绘,再进行transform才有用
this.$nextTick(() => {
el.style.webkitTransform = 'translate3d(0,0,0)';//外层做纵向运动
el.style.transform = 'translate3d(0,0,0)';
let inner = el.getElementsByClassName('inner-hook')[0];
inner.style.webkitTransform = 'translate3d(0,0,0)';
inner.style.transform = 'translate3d(0,0,0)';
});
},
afterEnter: function (el) {
let ball = this.dropBalls.shift();
if(ball) {
ball.show = false;
el.style.display = 'none';
}
}
[code].ball-container {
.ball {
position: fixed;
left: 32px;
bottom: 22px;
width: 16px;
heigth: 16px;
z-index: 200;
.inner {
width: 16px;
height: 16px;
border-radius: 50%;
background: rgb(0,160,220);
}
&.drop-enter-active,&.drop-leave-active {
transition: all 0.4s cubic-bezier(0.49,-0.29,0.75,0.41);
.inner {
transition: all 0.4s linear;
}
}
}
}

 

阅读更多
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: