视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
vue 2.0 购物车小球抛物线的示例代码
2020-11-27 22:20:40 责编:小采
文档


本文介绍了vue 2.0 购物车小球抛物线的示例代码,分享给大家,具体如下:

备注:此项目模仿 饿了吗。我用的是最新的Vue, 视频上的一些写法已经被废弃了。

布局代码

<div class="ball-container">
 <transition name="drop"
 v-for="ball in balls"
 @before-enter="beforeDrop"
 @enter="dropping"
 @after-enter="afterDrop">
 <div v-show="ball.show" class="ball" v-bind:css="false">
 <div class="inner inner-hook" ></div>
 </div>
 </transition>
</div>

css代码(使用stylus写法)

.ball-container
 .ball
 position fixed
 left 32px
 bottom 22px
 z-index 200
 transition all 0.4s cubic-bezier(0.49,-0.29,0.75,0.41)
 .inner
 width 16px
 height 16px
 border-radius 50%
 background-color rgb(0,160,220)
 transition all 0.4s linear

js代码

data() {
 return {
 balls : [
 {
 show: false
 },
 {
 show: false
 },
 {
 show: false
 },
 {
 show: false
 },
 {
 show: false
 }
 ],
 dropBalls: []
 };
}, 
methods: {
 drop(el) {
 for(let i = 0; i < this.balls.length; i++) {
 let ball = this.balls[i];
 if(!ball.show) {
 ball.show = true;
 ball.el = el;
 this.dropBalls.push(ball);
 return ;
 }
 }
 }
 beforeDrop(el) {
 let count = this.balls.length;
 while (count--) {
 let ball = this.balls[count];
 if(ball.show) {
 let rect = ball.el.getBoundingClientRect();
 let x = rect.left - 32;
 let y = -(window.innerHeight - rect.top - 22);
 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)`;
 }
 }
 },
 dropping(el) {
 /* eslint-disable no-unused-vars */
 let rf = el.offsetHeight;
 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)';
 });
 },
 afterDrop(el){
 let ball = this.dropBalls.shift();
 if(ball) {
 ball.show = false;
 el.style.display = 'none';
 }
 }
}

getBoundingClientRect()。方法请阅读这篇文章//www.gxlcms.com/article/134208.htm

说明:

goods 是一个组件,里面包含menu(div) , foods(div), shopcart(购物车组件)。其中foods 包含cartcontrol(即小球组件)

组件之间的通信:说明:菜单和商品

第1个问题:小球,需要获取所点击的商品的数量。

利用Vue的props,将foods值传递给cartcontrol。但是这样有个问题。即子组件更新,无法同步回父组件。且,在子组件中,对food注册了一个count属性,此属性也无法同步回父组件(goods)。

解决方法:

导入全局的Vue。

利用Vue.set(target,key,value); 对 target注册count;

第2个问题:小球点击,将所点击过的商品数目传递给 shopcart。

在goods的 computed:{} 定义一个方法,将该方法以props的方式,传递给shopcart。

因为,shopcart,对传递过去的数据仅数据运算(不会改变)。因此不用同步会父组件。

第3个问题:购物车小球做抛物线运动。

对于购物车小球做抛物线运动。首先,落点都在购物车,小球则是随机的。要做抛物线运动,就要获取,所点击的 + 号的x,y位置。其次,抛物线运动,只有在enter--> enter-to这段期间有,在leave--> leave-to 期间是没有的,因此,需要用Vue提供的钩子函数。

获取 + 号x,y 位置:

小球(cartcontrol)是子组件。需要把数据传递给 goods(父组件)。可以使用Vuex,或者直接使用事件总线。对于饿了吗demo。直接使用事件总线。

创建一个 空的Vue。在 cartcontrol 中 ,通过 Bus.$emit(key, ... arg); 注册一个监听,然后再父组件 通过Bus.$on(key, function(... arg));监听此方法。将所操作的 dom 对象传递过去即可

Vue提供的钩子

这里要说明一点,Vue在他的官网,对于只有过度的js,done是必须的,当我加上done的时候,after-enter方法无法被执行。
还有1个问题,Vue官网推荐,只有过度效果,在做过度动画的元素上加上v-bind:class='false'。之前没加,出现了,小球只能在第1次点击的地方做过度效果。

下载本文
显示全文
专题