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 相关文章推荐
实现png图片和png背景透明(支持多浏览器)的方法
Sep 08 Javascript
jQuery源码分析之Event事件分析
Jun 07 Javascript
初窥JQuery(一)jquery选择符 必备知识点
Nov 25 Javascript
初窥JQuery(二) 事件机制(1)
Nov 25 Javascript
js仿百度贴吧验证码特效实例代码
Jan 16 Javascript
jquery禁止输入数字以外的字符的示例(纯数字验证码)
Apr 10 Javascript
使用JavaScript实现弹出层效果的简单实例
May 31 Javascript
js匿名函数作为函数参数详解
Jun 01 Javascript
JavaScript比较当前时间是否在指定时间段内的方法
Aug 02 Javascript
vue-router单页面路由
Jun 17 Javascript
Javascript网页抢红包外挂实现分享
Jan 11 Javascript
Vue.js获取手机系统型号、版本、浏览器类型的示例代码
May 10 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中慎用双等于(==)的详解
2013/06/06 PHP
详谈PHP文件目录基础操作
2014/11/11 PHP
Yii2.0表关联查询实例分析
2016/07/18 PHP
PHP正则匹配反斜杠'\'和美元'$'的方法
2017/02/08 PHP
laravel7学习之无限级分类的最新实现方法
2020/09/30 PHP
远离JS灾难css灾难之 js私有函数和css选择器作为容器
2011/12/11 Javascript
jquery实现显示已选用户
2014/07/21 Javascript
jquery实现个人中心导航菜单效果和美观都非常不错
2014/09/02 Javascript
jQuery实现滑动页面固定顶部显示(可根据显示位置消失与替换)
2015/10/28 Javascript
js实现千分符和保留几位小数的简单实例
2016/08/01 Javascript
浅谈Vue.js
2017/03/02 Javascript
微信小程序的分类页面制作
2017/06/27 Javascript
在vue里使用codemirror遇到的问题
2018/11/01 Javascript
js脚本中执行java后台代码方法解析
2019/10/11 Javascript
[46:27]DOTA2上海特级锦标赛主赛事日 - 1 胜者组第一轮#2LGD VS MVP.Phx第一局
2016/03/02 DOTA
PHP webshell检查工具 python实现代码
2009/09/15 Python
python实现爬虫统计学校BBS男女比例(一)
2015/12/31 Python
pandas 选择某几列的方法
2018/07/03 Python
Python判断中文字符串是否相等的实例
2018/07/06 Python
python django model联合主键的例子
2019/08/06 Python
Python编程学习之如何判断3个数的大小
2019/08/07 Python
tensorflow常用函数API介绍
2020/04/19 Python
python 实现图像快速替换某种颜色
2020/06/04 Python
python实现移动木板小游戏
2020/10/09 Python
使用CSS3实现多列布局与多背景的技巧
2016/02/29 HTML / CSS
HTML5 input新增type属性color颜色拾取器的实例代码
2018/08/27 HTML / CSS
仓库班组长岗位职责
2013/12/12 职场文书
大学生求职自我评价
2014/01/16 职场文书
计算机专业毕业生自荐书
2014/06/02 职场文书
自主招生学校推荐信
2014/09/26 职场文书
晚会开幕词
2015/01/28 职场文书
志愿者服务活动总结报告
2015/05/06 职场文书
董事长致辞
2015/07/29 职场文书
小学四年级班务总结该怎么写?
2019/08/16 职场文书
美甲店的创业计划书模板
2019/08/23 职场文书
Windows server 2016服务器基本设置
2022/08/14 Servers