Vue实现商品飞入购物车效果(电商项目)


Posted in Javascript onNovember 26, 2019

各位掘友,好久不见,最近利用工作之余开源了Vue电商项目,高仿某知名O2O买菜平台,整个项目做下来收获还是蛮多的,可以扫描下方二维码体验,本篇是项目的核心知识拆解篇,主要是拆解增加商品飞入购物车的实现过程。

Vue实现商品飞入购物车效果(电商项目)

点我体验

项目开源地址 感谢点星+收藏

首先我先简单的介绍下本项目所用到的技术栈:

整个项目采用 vue-cli3 脚手架搭建, Vue全家桶(vue、vuex、vue-router)Vant UI框架 以及很多著名好用的第三方库如: axiosfastclickbetter-scrolltwix.jspubsub.jsmoment.jsvue-amap 等等。 像素单位选择 rem ,后台数据接口通过 Easy-Mock 搭建,以最接近企业开发的方式,组件化模块化,最大程度实现高内聚低耦合,大大提升各模块的可维护及可扩展性,相信读完源码和我写的系列拆解文章,无论你是哪个段位的攻城狮都会有所启发!开源不易,你的点赞就是对我最大的鼓励:tada::tada:感谢~Thanks♪(・ω・)ノ

二、增加商品飞入购物车实现过程

首先先来瞅瞅要做成的样子,是不是很炫酷:airplane::airplane:随手点赞支持下作者:heartbeat:

Vue实现商品飞入购物车效果(电商项目)

实现思路

首先我们先来把关注点放到加入购物车这块,当我们点击购物车图标的时候,这个时候会在当前点击的商品图片的中央范围先出现个圆形的商品缩略图,其次这个商品缩略图会沿着当前位置以曲线的形式逐渐变小飞入到购物车里,当商品飞入到购物车时,购物车的数字图标会增加,同时购物车会出现弹簧动画。

通过上面大白话分析整个实现步骤可简短分为三个阶段来完成编码:

  • 第一阶段:点击购物车,出现一个商品缩略图的小球
  • 第二阶段:商品缩略小球以曲线形式从当前位置飞到底部购物车的位置
  • 第三阶段:当商品缩略小球完全消失在购物车位置时,购物车数量图标加1,且实现弹簧动画.

第一阶段代码实现

第一阶段编码:绘制一个圆形的小球到商品的中间区域 这个非常简单,就是在商品图片区域加一个 div ,设置 position:fixed 及宽度高度等,但是呢?

先埋个问题,如何让小球出现在点击当前商品的范围内呢?

阶段一踩坑

起初我通过计算属性遍历了商品列表,在所有的商品视图中加入商品缩略图小球,然后,通过给每个商品列表里增加一个boolean属性 show ,通过点击购物车图标来控制我刚创建的小球的显示与隐藏,然后自己就进入了死胡同,饶了半天,计算属性的数据通过 set 方式改变后,Dom死活不听话就是不按套路出牌(因为计算属性存在数据缓存),于是不得已放弃此笨拙的办法。

阶段一最终实现方案

上面踩坑是因为贪多,想一次性到位,提前加载所有商品的小球缩略图,然后通过点击购物车来控制当前商品缩略图的显示与隐藏.那么我们要不换一种思路,仅创建一个缩略小球怎么样,通过 boolean 来控制它的显示和隐藏,位置动态变化,点击哪个商品就让他显示到哪个商品的范围内,并且每次点击给他设置个true的属性丢到一个数组中.好,我们先在data中定义小球是否显示的属性及显示小球的数组

data () {
 return {
  showMoveDot: [], //控制下落的小圆点显示隐藏
 }

 

然后我们在点击购物车的时候来给 showMoveDot 数组动态增加属性,然后在Dom中遍历这个数组,双向绑定,最后通过 v-if 来控制显示和隐藏,这样是不是非常妙~~

点击购物车给 showMoveDot 增加 true 的属性

methods: {
addToCart (product, num) {
 this.showMoveDot = [...this.showMoveDot, true];
 }
}

 

Dom中遍历 showMoveDot ,并且通过 v-if 来控制商品缩略小球的显示

<div
 v-for="(item,index) in showMoveDot"
 :key="index">
 <div class="move_dot"
   ref="ball"
   v-if="item">
 </div>
</div>

 

此时点击购物车图标就会在当前商品中出现商品缩略图的小球,至此,阶段一大功告成 ✿✿?(°?°)ノ✿ ~

第二阶段代码实现

本阶段需要用到动画知识,所以首先想到的是Vue的 transition 属性,首先给缩略图的小球包一层 transition 并且增加 appear 动画并且实现 beforeEnterafterEnter 事件方法,所以此时修改Dom代码

<transition appear
    @before-appear="beforeEnter"
    @after-appear='afterEnter'
    v-for="(item,index) in showMoveDot"
    :key="index.id">
 <div class="move_dot"
   ref="ball"
   v-if="item">
 </div>
 </transition>

 

上面Dom代码的两个方法 beforeEnterafterEnter 方法分别是动画初次渲染前和动画渲染后,那么我们就要把注意点放到这两个状态中. 在初次渲染的时候我们确定下小球的位置,那么这个时候我们就要用到一个方法 getBoundingClientRect ,这个方法返回的是一组矩形的集合,这下就好啦,可以通过这个方法来定位某个元素在屏幕中的位置啦:blush:~

Vue实现商品飞入购物车效果(电商项目)

那好,那我们这个时候就成热打铁,通过这个方法先来确定点击购物车图标的时候,购物车这个小图标距左边和顶部相对屏幕的距离。

Vue实现商品飞入购物车效果(电商项目)

定义两个 data 来接受点击增加购物车图标获取到的值.

data () {
 return {
  showMoveDot: [], //控制下落的小圆点显示隐藏
  elLeft: 0, //当前点击购物车按钮在网页中的绝对top值
  elTop: 0, //当前点击购物车按钮在网页中的绝对left值
 }

 

然后我们在点击添加购物车的方法里获取位置。

methods: {
 addToCart () {
  this.showMoveDot = [...this.showMoveDot, true];
  this.elLeft = event.target.getBoundingClientRect().left;
  this.elTop = event.target.getBoundingClientRect().top;
 }
}

此时就获取到了点击加入购物车图标的位置啦:v:这个时候离成功进了一大半~ 获取到增加购物车图标的距离后,通过相对位置来确定商品缩略小球的位置,于是在动画渲染前我们设置下他的 transform 值,x,y的值自己可以调整,并且让他的透明度为0,暂时不显示.

beforeEnter (el) {
   // 设置transform值
   el.style.transform = `translate3d(${this.elLeft - 30}px,${this.elTop - 100}px , 0)`;
   // 设置透明度
   el.style.opacity = 0;
  },

接下来就是关键,如何让小球从当前位置移动到底部 Tabbar 的购物车中呢?同样的方法,我们通过 getBoundingClientRect 方法来确定底部Tabbar的购物车徽标的 lefttop 值,获取到这个值后,就让小球在当前位置,以贝塞尔曲线的方式向购物车x和y的方向移动,当移动完成后将数组 showMoveDot 的属性设置为 false 且透明度为1.

Vue实现商品飞入购物车效果(电商项目)

在小球绘制完成后的方法中

afterEnter (el) {
  // 获取底部购物车徽标
  const badgePosition = document
  .getElementById("buycar")
  .getBoundingClientRect();
  // 设置小球移动的位移
  el.style.transform = `translate3d(${badgePosition.left + 30}px,${badgePosition.top - 30}px,0)`
  // 增加贝塞尔曲线 
  el.style.transition = 'transform .88s cubic-bezier(0.3, -0.25, 0.7, -0.15)';
  el.style.transition = 'transform .88s linear';
  this.showMoveDot = this.showMoveDot.map(item => false);
  // 设置透明度
  el.style.opacity = 1;
 }

 

此时大功告成!点击添加购物车按钮,小球可以曲线飞到购物车中了,来个Gif图炫耀下✿✿?(°?°)ノ✿

Vue实现商品飞入购物车效果(电商项目)

掘友请留步(??^??)你以为这样就算完成了嘛~对于Geek:monkey_face:来说,这样的效果,简直太Low啦,于是乎,咱们继续一起来做个优化吧~

阶段三 体验优化

优化一:把小球变成点击当前商品的图片

刚开始还真TM把我给难住了,这么多图片,鬼知道显示哪个呢?后来灵机一动,不就是个动态加载图片嘛,点击加入购物车的时候当前的商品对象已经拿到了,你怕啥,直接取就完啦!~so easy:smile:好,思路有了,那咱就上代码!

1.在data中追加个 dropImage 属性.

data () {
 return {
  showMoveDot: [], //控制下落的小圆点显示隐藏
  elLeft: 0, //当前点击购物车按钮在网页中的绝对top值
  elTop: 0, //当前点击购物车按钮在网页中的绝对left值
  dropImage: '' // 小球图片
 }

 

2.在Dom中通过动态绑定的方式来获取 dropImage

<transition appear
     @after-appear='afterEnter'
     @before-appear="beforeEnter"
     v-for="(item,index) in showMoveDot"
     :key="index.id">
  <div class="move_dot"
    ref="ball"
    v-if="item">
   <!-- 小球图片 -->
   <img :src="dropImage"
    alt="">
  </div>
  </transition>

 

3.动态给 dropImage 赋值

addToCart (product) {
  // 取出商品的图片
  this.dropImage = product.small_image;
  // 将商品添加到购物车中
  this.ADD_TO_CART(product);
  // 购物车左边的
  this.elLeft = event.target.getBoundingClientRect().left;
  this.elTop = event.target.getBoundingClientRect().top;
  this.showMoveDot = [...this.showMoveDot, true];
 },

 

好啦!此时我们就完成了小球图片的动态加载,来个Gif图炫一哈✿✿?(°?°)ノ✿

Vue实现商品飞入购物车效果(电商项目)

但是有木有发现个问题,图片飞过去很突兀,直来直去的,不够友好,行那咱继续优化~~

优化二:飞入购物车的商品缩略图逐渐变小

哈哈~让商品飞入的时候逐渐变小,思来想去,还是用 css3keyframes 来搞比较好,废话不多说直接上代码.

1.设置 keyframes 的值

@keyframes mymove {
 0% {
  transform: scale(1);
 }
 25% {
  transform: scale(0.8);
 }
 50% {
  transform: scale(0.6);
 }
 75% {
  transform: scale(0.4);
 }
 100% {
  transform: scale(0.2);
 }
 }

2.给商品缩略图添加 animation 并加入 keyframes

img {
  animation: 0.88s mymove ease-in-out;
  width: 3rem;
  height: 3rem;
  border-radius: 50%;
  }

好嘞,搞定!来个Gif图炫一哈✿✿?(°?°)ノ✿

Vue实现商品飞入购物车效果(电商项目)

为啥我觉得还是有点突兀呢,没办法,处女座,必须让他更完美:see_no_evil:

优化三:购物车加入商品后弹簧效果

商品缩略小球逐渐变小的落入到购物车中,此时,购物车再来个弹簧效果就更美了,还是老办法用 css3keyframes 再合适不过啦~

由于Tabbar是用的 Vant UI组件,在单独的 Dashboard.vue 文件中,所以在 Dashboard.vue 文件中给购物车这个图标设置 keyframes 值.

@keyframes carmove {
 0% {
 transform: scale(1);
 }
 25% {
 transform: scale(0.8);
 }
 50% {
 transform: scale(1.1);
 }
 75% {
 transform: scale(0.9);
 }
 100% {
 transform: scale(1);
 }
}

并且把这个 keyframes 值设置给购物车这个图标

.moveToCart {
 animation: mymove 0.5s ease-in-out;
}

购物车的动画是加完了,但是如何控制小球移入到购物车后让动画生效呢?于是先找到小球动画结束的方法,通过查资料找到了 transitionendwebkitAnimationEnd 两个方法,于是我对他们做了监听,当小球消失的时候在这两个方法中动态的增加Tabbar底部购物车的 keyframes 值.

 

afterEnter (el) {
  // 监听小球动画结束方法
  el.addEventListener('transitionend', () => {
  el.style.display = 'none';
  this.listenInCart();
  })
  // 监听小球动画结束方法
  el.addEventListener('webkitAnimationEnd', () => {
  el.style.display = 'none';
  this.listenInCart();
  })
 },

this.listenInCart() 方法是控制底部Tabbar购物车图标动画的方法,我们已经定义了一个class moveToCart ,我采用取巧的办法,当动画结束的时候,给Tabbar的购物车添加class moveToCart ,然后让他在500ms后在移除这个class,这样就会保证每次增加购物车后,底部Tabbar都会执行 keyframs 动画.

listenInCart () {
  // 拿到底部Tabbar购物车的DOM元素添加class
  document.getElementById("buycar").classList.add('moveToCart');
  setTimeout(() => {
  // 500毫秒后移除底部Tabbar购物车的DOM元素class
  document.getElementById("buycar").classList.remove('moveToCart');
  }, 500);
 }

此时算是真正的大功告成:cherry_blossom:,来个Gif图炫耀一哈✿✿?(°?°)ノ✿

Vue实现商品飞入购物车效果(电商项目)

都看到这里啦,还不点赞支持下:smile:,鼓励下作者~ 三、重点来了:rocket::rocket:

我知道掘友们已经迫不及待的想看源码啦~当然本篇知识点只是整个项目的冰山一角,还有很多好用好玩的新技术,如 Better-scroll 滚动使用,高德地图的集成,图片瀑布流,移动端适配等等主流技术在这个项目中几乎都有~放个GitHub连接,掘友们可不要吝啬手中的小星星哦✿✿?(°?°)ノ✿

:tada:Vue构建大型单页面电商应用 开源啦!点我看源码:rocket::rocket:

总结

以上所述是小编给大家介绍的Vue实现商品飞入购物车效果,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

Javascript 相关文章推荐
JavaScript中的Screen屏幕对象
Jan 16 Javascript
Jquery实现仿腾讯娱乐频道焦点图(幻灯片)特效
Mar 06 Javascript
JavaScript实现鼠标滑过图片变换效果的方法
Apr 16 Javascript
如何使用jquery修改css中带有!important的样式属性
Apr 28 Javascript
基于JS快速实现导航下拉菜单动画效果附源码下载
Oct 27 Javascript
利用js来实现缩略语列表、文献来源链接和快捷键列表
Dec 16 Javascript
使用jQuery的load方法设计动态加载及解决被加载页面js失效问题
Mar 01 Javascript
jQuery插件zTree实现的多选树效果示例
Mar 08 Javascript
JavaScript之RegExp_动力节点Java学院整理
Jun 29 Javascript
Node.js中package.json中库的版本号(~和^)
Apr 02 Javascript
8个有意思的JavaScript面试题
Jul 30 Javascript
解决vue初始化项目一直停在downloading template的问题
Nov 09 Javascript
使用Vue生成动态表单
Nov 26 #Javascript
vue实现在线预览pdf文件和下载(pdf.js)
Nov 26 #Javascript
Vue+ElementUI使用vue-pdf实现预览功能
Nov 26 #Javascript
详解小程序如何动态绑定点击的执行方法
Nov 26 #Javascript
vue element-ui读取pdf文件的方法
Nov 26 #Javascript
Vue+Element-UI实现上传图片并压缩
Nov 26 #Javascript
jQuery实现轮播图效果
Nov 26 #jQuery
You might like
浅析PHP微信支付通知的处理方式
2014/05/25 PHP
php实现给图片加灰色半透明效果的方法
2014/10/20 PHP
详解PHP字符串替换str_replace()函数四种用法
2017/10/13 PHP
php-fpm超时时间设置request_terminate_timeout资源问题分析
2019/09/27 PHP
php设计模式之模板模式实例分析【星际争霸游戏案例】
2020/03/24 PHP
javascript 鼠标悬浮图片显示原图 移出鼠标后原图消失(多图)
2009/12/28 Javascript
javascript简单性能问题及学习笔记
2014/02/04 Javascript
IE6已终止操作问题的2种情况及解决
2014/04/23 Javascript
基于jquery实现的树形菜单效果代码
2015/09/06 Javascript
深入理解javascript函数参数与闭包
2016/12/12 Javascript
浅析上传头像示例及其注意事项
2016/12/14 Javascript
jquery实现折叠菜单效果【推荐】
2017/03/08 Javascript
VsCode新建VueJs项目的详细步骤
2017/09/23 Javascript
React Native 使用Fetch发送网络请求的示例代码
2017/12/02 Javascript
element-ui组件table实现自定义筛选功能的示例代码
2019/03/15 Javascript
wxPython 入门教程
2008/10/07 Python
Python Deque 模块使用详解
2014/07/04 Python
flask入门之表单的实现
2018/07/18 Python
django url到views参数传递的实例
2019/07/19 Python
Python numpy数组转置与轴变换
2019/11/15 Python
THE OUTNET英国官网:国际设计师品牌折扣网站
2016/08/14 全球购物
美国娱乐和流行文化商品店:FYE
2017/09/14 全球购物
巴西美妆购物网站:Kutiz Beauté
2019/03/13 全球购物
mysql有关权限的表都有哪几个
2015/04/22 面试题
室内设计专业个人的自我评价
2013/10/19 职场文书
共产党员承诺书
2014/03/25 职场文书
品质口号大全
2014/06/17 职场文书
2014年客房服务员工作总结
2014/11/18 职场文书
我们的节日重阳节活动总结
2015/03/24 职场文书
医院病假条范文
2015/08/17 职场文书
2016年习主席讲话学习心得体会
2016/01/20 职场文书
应届生个人的求职(自荐信范文2篇)
2019/08/23 职场文书
百善孝为先:关于孝道的经典语录
2019/10/18 职场文书
浅谈vue2的$refs在vue3组合式API中的替代方法
2021/04/18 Vue.js
Django debug为True时,css加载失败的解决方案
2021/04/24 Python
全网非常详细的pytest配置文件
2022/07/15 Python