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 相关文章推荐
一实用的实现table排序的Javascript类库
Sep 12 Javascript
javascript-简单的日历实现及Date对象语法介绍(附图)
May 30 Javascript
js禁止回车提交表单的示例代码
Dec 23 Javascript
用IE重起计算机或者关机的示例代码
Mar 10 Javascript
js验证IP及子网掩码的合法性有效性示例
Apr 30 Javascript
JS实现可关闭的对联广告效果代码
Sep 14 Javascript
js实现固定宽高滑动轮播图效果
Jan 13 Javascript
Angular.JS实现无限级的联动菜单(使用demo)
Feb 08 Javascript
基于jQuery实现的Ajax 验证用户名唯一性实例代码
Jun 28 jQuery
详解Vue Elememt-UI构建管理后台
Feb 27 Javascript
在antd Form表单中select设置初始值操作
Nov 02 Javascript
vue项目中的支付功能实现(微信支付和支付宝支付)
Feb 18 Vue.js
使用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
ubuntu12.04使用c编写php扩展模块教程分享
2013/12/25 PHP
PHP单态模式简单用法示例
2016/11/16 PHP
php使用include 和require引入文件的区别
2017/02/16 PHP
Laravel模型事件的实现原理详解
2018/03/14 PHP
thinkPHP利用ajax异步上传图片并显示、删除的示例
2018/09/26 PHP
JS 自动完成 AutoComplete(Ajax 查询)
2009/07/07 Javascript
javascript 按回车键相应按钮提交事件
2009/11/02 Javascript
jQuery验证Checkbox是否选中的代码 推荐
2011/09/04 Javascript
JS获取屏幕,浏览器窗口大小,网页高度宽度(实现代码)
2013/12/17 Javascript
用nodejs实现PHP的print_r函数代码
2014/03/14 NodeJs
js图片处理示例代码
2014/05/12 Javascript
详解JavaScript中的forEach()方法的使用
2015/06/08 Javascript
Javascript函数式编程简单介绍
2015/10/11 Javascript
js表单验证实例讲解
2016/03/31 Javascript
jquery使用EasyUI Tree异步加载JSON数据(生成树)
2017/02/11 Javascript
如何正确理解javascript的模块化
2017/03/02 Javascript
Vuex中的State使用介绍
2019/01/19 Javascript
解决layui laydate 时间控件一闪而过的问题
2019/09/28 Javascript
python判断、获取一张图片主色调的2个实例
2014/04/10 Python
python实现井字棋游戏
2020/03/30 Python
Python进阶_关于命名空间与作用域(详解)
2017/05/29 Python
python如何实现从视频中提取每秒图片
2020/10/22 Python
python GUI库图形界面开发之PyQt5控件QTableWidget详细使用方法与属性
2020/02/25 Python
python新式类和经典类的区别实例分析
2020/03/23 Python
加拿大城市本地限时优惠:Buytopia.ca
2018/09/19 全球购物
澳大利亚玩具剧场:Toy Playhouse
2019/03/03 全球购物
阿迪达斯香港官网:adidas香港
2019/11/09 全球购物
几个常见的消息中间件(MOM)
2014/01/08 面试题
教师实习期自我鉴定
2013/10/06 职场文书
自主招生自荐书
2013/11/29 职场文书
犯错检讨书
2014/02/21 职场文书
国际经济与贸易专业大学生职业规划书
2014/03/01 职场文书
幼儿园清明节活动总结
2014/07/04 职场文书
专题组织生活会思想汇报
2014/10/01 职场文书
闪闪红星观后感
2015/06/08 职场文书
vue3不同环境下实现配置代理
2022/05/25 Vue.js