vue实现购物车抛物线小球动画效果的方法详解


Posted in Javascript onFebruary 13, 2019

本文实例讲述了vue实现购物车抛物线小球动画效果的方法。分享给大家供大家参考,具体如下:

vue实现购物车抛物线小球动画效果的方法详解

先上最终效果图,在商品页面和商品详情页面点击加号添加商品时都可以看到小球抛物线落入购物车的动画效果

此文章只写了商品页面购物小球的实现,商品详情页原理类似

实现步骤:

1. 需要三个组件,最下方包含蓝色购物车的【购物车】组件shopCart.vue(子组件),每个【加减号】组成的购物小球组件cartControl.vue(子组件),和包含每个商品信息的goods组件goods.vue(父组件)

2. 原理,购物小球组件在点击加号的时候对外触发事件,将小球对象本身传递给父组件goods组件,再由goods作为桥梁将这个信息传递给另一个子组件shopCart组件,shopCart组件获取到小球对象后,对该小球进行位置计算,从而实现从不同商品的位置添加商品的抛物线小球效果

3. cartControl.vue部分代码

html代码

<div class="cartControl">
  <transition name="move">
  <!--减少商品-->
  <div class="decrease " v-show="food.count>0" @click.stop.prevent="decreaseCart">
   <span class="inner iconfont"></span>
  </div>
  </transition>
  <!--增加商品-->
  <div class="count" v-show="food.count>0">{{food.count}}</div>
  <!--点击加号按钮,触发事件addCart,将事件对象作为参数传递-->
  <div class="add iconfont" @click.stop.prevent="addCart($event)">?</div>
</div>

js代码

// addCart事件
addCart (event) {
  if (!event._constructed) return // 检测事件派发是否来自于better-scroll
  if (!this.food.count) {
  // 当给一个观测对象添加一个它不存在的属性的时候,直接赋值是不可以的,需要使用Vue.set设置这个属性
  Vue.set(this.food, 'count', 1)
  } else {
  this.food.count++
  }
  this.$emit('cart-add', event.target) // 向父组件触发一个自定义的cart-add事件,同时将事件对象传递给父组件
},

4. goods.vue部分代码

html代码

<!--加减商品-->
<div class="cartControl-wrapper">
 <!--在父组件监听到子组件触发的cart-add事件-->
 <cart-control :food="food" @cart-add="handlecartAdd"></cart-control>
</div>

js代码 知识点:子组件和父组件之间的数据传递

_drop (target) { // 在goods.vue定义 _drop方法将cartcontrol的传递过来target对象再传递给shopCart
  this.$nextTick(() => { // 使用$nextTick优化体验
  this.$refs.shopCart.drop(target) // 父组件goods通过.$refs属性访问shopCart子组件的drop方法
  })
},
handlecartAdd (target) { // 点击加号按钮触发事件
  this._drop(target)  // 调用_drop方法
}

5. shopCart.vue部分代码

①.定义一个数组,存放5个小球,这5个小球可以满足的动画的运行

②.动画分为两层,外层控制小球y轴方向和运动的轨道,内层控制x轴方向的运动

③.使用js动画钩子,vue在实现动画的时候提供了几个javascript钩子,可配合css动画一起使用,也可单独使用,因为购物车抛物线小球只有进入动画,没有离开的动画,所以enter的钩子有,before-enter,enter,after-enter,这些钩子需要在html属性中声明,然后在methods中使用这些方法

可参考以下官网

https://cn.vuejs.org/v2/guide/transitions.html#JavaScript-%E9%92%A9%E5%AD%90

④.v-show控制盒子的显示和隐藏

html

<!--购物车小球-->
  <div class="ball-container">
  <div v-for="(ball,index) of balls" :key="index">
   <transition @before-enter="handleBeforeEnter"
      @enter="handleEnter"
      @after-enter="handleAfterEnter">
   <div class="ball" v-show="ball.show" v-bind:css="false"><!--外层盒子-->
    <div class="inner inner-hook"></div> <!--内层盒子-->
   </div>
   </transition>
  </div>
  </div>

data

data () {
 return { // 使用balls存放5个小球,这些小球的默认状态都是不显示的
  balls: [{show: false}, {show: false}, {show: false}, {show: false}, {show: false}],
  dropBalls: [] // 用dropBalls来存放掉落的小球
 }
}

在methods中定义方法

// 当触发drop方法时小球开始掉落
drop (el) {
  for (let i = 0; i < this.balls.length; i++) { // 遍历这5个小球
  let ball = this.balls[i]
  if (!ball.show) { // 当小球显示状态为隐藏时
   ball.show = true // 将这个小球的显示状态设置为true
   ball.el = el  // 将cartControl传过来的对象挂载到ball的el属性上
   this.dropBalls.push(ball) // 将这个小球放入到dropBalls数组中
   return
  }
  }
}

js动画

// js动画钩子
// beforeenter
handleBeforeEnter: function (el) {
  let count = this.balls.length 
  while (count--) {
  let ball = this.balls[count]
  if (ball.show) {
   let rect = ball.el.getBoundingClientRect() // getBoundingClientRect()获取小球相对于视窗的位置,屏幕左上角坐标为0,0
   let x = rect.left - 32 // 小球x方向位移= 小球距离屏幕左侧的距离-外层盒子距离水平的距离
   let y = -(window.innerHeight - rect.top - 22) // 负数,因为是从左上角向下
   el.style.display = ''
   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)`
  }
  }
},
// enter
handleEnter: function (el, done) {
  /* 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)'
  el.addEventListener('transitionend', done) // Vue为了知道过渡的完成,必须设置相应的事件监听器。它可以是transitionend或 animationend
  })
},
handleAfterEnter: function (el) {
  let ball = this.dropBalls.shift() // 完成一次动画就删除一个dropBalls的小球
  if (ball) {
  ball.show = false
  el.style.display = 'none'
  }
},

希望本文所述对大家vue.js程序设计有所帮助。

Javascript 相关文章推荐
一个高效的JavaScript压缩工具下载集合
Mar 06 Javascript
超级简单的图片防盗(HTML),好用
Apr 08 Javascript
JavaScript 字符编码规则
May 04 Javascript
jQuery 行背景颜色的交替显示(隔行变色)实现代码
Dec 13 Javascript
EXTJS记事本 当CompositeField遇上RowEditor
Jul 31 Javascript
JQUERY1.6 使用方法四 检测浏览器
Nov 23 Javascript
Angular2环境搭建具体操作步骤(推荐)
Aug 04 Javascript
vue实现商品加减计算总价的实例代码
Aug 12 Javascript
微信小程序实现复选框效果
Dec 28 Javascript
Vue scrollBehavior 滚动行为实现后退页面显示在上次浏览的位置
May 27 Javascript
Vue+ElementUI项目使用webpack输出MPA的方法
Aug 27 Javascript
node.js爬虫框架node-crawler初体验
Oct 29 Javascript
Jquery实现无缝向上循环滚动列表的特效
Feb 13 #jQuery
vuex实现的简单购物车功能示例
Feb 13 #Javascript
jquery无缝图片轮播组件封装
Nov 25 #jQuery
Vue中多个元素、组件的过渡及列表过渡的方法示例
Feb 13 #Javascript
vue写h5页面的方法总结
Feb 12 #Javascript
如何将百度地图包装成Vue的组件的方法步骤
Feb 12 #Javascript
微信小程序websocket聊天室的实现示例代码
Feb 12 #Javascript
You might like
虹吸式咖啡壶操作
2021/03/03 冲泡冲煮
PHP批量生成缩略图的代码
2008/07/19 PHP
php去除HTML标签实例
2013/11/06 PHP
PHP编程文件处理类SplFileObject和SplFileInfo用法实例分析
2017/07/22 PHP
JavaScript效率调优经验
2009/06/04 Javascript
javascript dom 操作详解 js加强
2009/07/13 Javascript
jQueryUI的Dialog的简单封装
2010/06/07 Javascript
jQuery图片轮播的具体实现
2013/09/11 Javascript
nodeType属性返回被选节点的节点类型介绍
2013/11/22 Javascript
按下Enter焦点移至下一个控件的实现js代码
2013/12/11 Javascript
AspNet中使用JQuery boxy插件的确认框
2015/05/20 Javascript
JS简单设置下拉选择框默认值的方法
2016/08/20 Javascript
微信小程序 获取微信OpenId详解及实例代码
2016/10/31 Javascript
微信小程序 跳转传参数与传对象详解及实例代码
2017/03/14 Javascript
JavaScript运动框架 解决防抖动问题、悬浮对联(二)
2017/05/17 Javascript
angularJs中$http获取后台数据的实例讲解
2018/08/08 Javascript
微信小程序实现下拉菜单切换效果
2020/03/30 Javascript
微信小程序实现的3d轮播图效果示例【基于swiper组件】
2018/12/11 Javascript
使用Node.js写一个代码生成器的方法步骤
2019/05/10 Javascript
微信小程序通过js实现瀑布流布局详解
2019/08/28 Javascript
python list 合并连接字符串的方法
2013/03/09 Python
RC4文件加密的python实现方法
2015/06/30 Python
详解Python中dict与set的使用
2015/08/10 Python
Pycharm2017版本设置启动时默认自动打开项目的方法
2018/10/29 Python
将Pytorch模型从CPU转换成GPU的实现方法
2019/08/19 Python
python中def是做什么的
2020/06/10 Python
使用keras实现非线性回归(两种加激活函数的方式)
2020/07/05 Python
Python如何将模块打包并发布
2020/08/30 Python
阿迪达斯德国官方网站:adidas德国
2017/07/12 全球购物
Coccinelle官网:意大利的著名皮具品牌
2019/05/15 全球购物
美国最大的购物网站:Amazon.com(亚马逊美国)
2020/05/23 全球购物
会计专业求职信范文
2015/03/19 职场文书
css3 实现文字闪烁效果的三种方式示例代码
2021/04/25 HTML / CSS
总结高并发下Nginx性能如何优化
2021/11/01 Servers
Spring Data JPA框架持久化存储数据到数据库
2022/04/28 Java/Android
oracle设置密码复杂度及设置超时退出的功能
2022/06/28 Oracle