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 相关文章推荐
jQuery代码优化 遍历篇
Nov 01 Javascript
JavaScript异步调用定时方法并停止该方法实现代码
Mar 16 Javascript
javascript中如何处理引号编码&amp;#034;
Aug 15 Javascript
javascript中数组的sort()方法的使用介绍
Dec 18 Javascript
ECMAScript6中Set/WeakSet详解
Jun 12 Javascript
JavaScript子窗口调用父窗口变量和函数的方法
Oct 09 Javascript
JS实现图片高亮展示效果实例
Nov 24 Javascript
使用jQuery5分钟快速搞定双色表格的简单实例
Aug 08 Javascript
使用vue实现点击按钮滑出面板的实现代码
Jan 10 Javascript
Angular.JS中select下拉框设置value的方法
Jun 20 Javascript
vue给input file绑定函数获取当前上传的对象完美实现方法
Dec 15 Javascript
使用js在layui中实现上传图片压缩
Jun 18 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
Avengerls vs KG BO3 第一场2.18
2021/03/10 DOTA
js实现ASP分页函数 HTML分页函数
2006/09/22 Javascript
获取任意Html元素与body之间的偏移距离 offsetTop、offsetLeft (For:IE5+ FF1 )[
2006/12/22 Javascript
juqery 学习之三 选择器 可见性 元素属性
2010/11/25 Javascript
对xmlHttp对象方法和属性的理解
2011/01/17 Javascript
JavaScript中访问节点对象的方法有哪些如何使用
2013/09/24 Javascript
JS获取当前使用的浏览器名字以及版本号实现方法
2016/08/19 Javascript
原生js图片轮播效果实现代码
2016/10/19 Javascript
基于jQuery制作小图标上下滑动特效
2017/01/18 Javascript
Vue.js -- 过滤器使用总结
2017/02/18 Javascript
原生JS中slice()方法和splice()区别
2017/03/06 Javascript
JS实现侧边栏鼠标经过弹出框+缓冲效果
2017/03/29 Javascript
js和jquery中获取非行间样式
2017/05/05 jQuery
jquery版轮播图效果和extend扩展
2017/07/18 jQuery
使用JS模拟锚点跳转的实例
2018/02/01 Javascript
微信小程序使用swiper组件实现类3D轮播图
2018/08/29 Javascript
vue element动态渲染、移除表单并添加验证的实现
2019/01/16 Javascript
Vue3 中的数据侦测的实现
2019/10/09 Javascript
Python判断字符串与大小写转换
2015/06/08 Python
Django实现的自定义访问日志模块示例
2017/06/23 Python
python删除不需要的python文件方法
2018/04/24 Python
Python 中的range(),以及列表切片方法
2018/07/02 Python
在scrapy中使用phantomJS实现异步爬取的方法
2018/12/17 Python
用Python从0开始实现一个中文拼音输入法的思路详解
2019/07/20 Python
Python提取PDF内容的方法(文本、图像、线条等)
2019/09/25 Python
Python 在局部变量域中执行代码
2020/08/07 Python
python collections模块的使用
2020/10/16 Python
运行python提示no module named sklearn的解决方法
2020/11/29 Python
Python实现树莓派摄像头持续录像并传送到主机的步骤
2020/11/30 Python
CSS3弹性盒模型flex box快速入门心得(必看篇)
2016/05/24 HTML / CSS
世界上最大的隐形眼镜商店:1-800 Contacts
2018/11/03 全球购物
学习全国两会精神心得体会范文
2014/03/17 职场文书
房屋租赁协议书范本
2014/04/10 职场文书
内勤岗位职责范本
2015/04/13 职场文书
基于MySql验证的vsftpd虚拟用户
2021/11/07 MySQL
把77A收信机改造成收音机
2022/04/05 无线电