欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

vue實(shí)現(xiàn)購物車拋物線小球動(dòng)畫效果的方法詳解

 更新時(shí)間:2019年02月13日 08:59:06   作者:honey_seve7n  
這篇文章主要介紹了vue實(shí)現(xiàn)購物車拋物線小球動(dòng)畫效果的方法,結(jié)合實(shí)例形式較為詳細(xì)的分析了vue.js實(shí)現(xiàn)拋物線動(dòng)畫效果購物車功能相關(guān)原理與操作注意事項(xiàng),需要的朋友可以參考下

本文實(shí)例講述了vue實(shí)現(xiàn)購物車拋物線小球動(dòng)畫效果的方法。分享給大家供大家參考,具體如下:

先上最終效果圖,在商品頁面和商品詳情頁面點(diǎn)擊加號(hào)添加商品時(shí)都可以看到小球拋物線落入購物車的動(dòng)畫效果

此文章只寫了商品頁面購物小球的實(shí)現(xiàn),商品詳情頁原理類似

實(shí)現(xiàn)步驟:

1. 需要三個(gè)組件,最下方包含藍(lán)色購物車的【購物車】組件shopCart.vue(子組件),每個(gè)【加減號(hào)】組成的購物小球組件cartControl.vue(子組件),和包含每個(gè)商品信息的goods組件goods.vue(父組件)

2. 原理,購物小球組件在點(diǎn)擊加號(hào)的時(shí)候?qū)ν庥|發(fā)事件,將小球?qū)ο蟊旧韨鬟f給父組件goods組件,再由goods作為橋梁將這個(gè)信息傳遞給另一個(gè)子組件shopCart組件,shopCart組件獲取到小球?qū)ο蠛?,?duì)該小球進(jìn)行位置計(jì)算,從而實(shí)現(xiàn)從不同商品的位置添加商品的拋物線小球效果

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>
  <!--點(diǎn)擊加號(hào)按鈕,觸發(fā)事件addCart,將事件對(duì)象作為參數(shù)傳遞-->
  <div class="add iconfont" @click.stop.prevent="addCart($event)"></div>
</div>

js代碼

// addCart事件
addCart (event) {
  if (!event._constructed) return // 檢測事件派發(fā)是否來自于better-scroll
  if (!this.food.count) {
  // 當(dāng)給一個(gè)觀測對(duì)象添加一個(gè)它不存在的屬性的時(shí)候,直接賦值是不可以的,需要使用Vue.set設(shè)置這個(gè)屬性
  Vue.set(this.food, 'count', 1)
  } else {
  this.food.count++
  }
  this.$emit('cart-add', event.target) // 向父組件觸發(fā)一個(gè)自定義的cart-add事件,同時(shí)將事件對(duì)象傳遞給父組件
},

4. goods.vue部分代碼

html代碼

<!--加減商品-->
<div class="cartControl-wrapper">
 <!--在父組件監(jiān)聽到子組件觸發(fā)的cart-add事件-->
 <cart-control :food="food" @cart-add="handlecartAdd"></cart-control>
</div>

js代碼 知識(shí)點(diǎn):子組件和父組件之間的數(shù)據(jù)傳遞

_drop (target) { // 在goods.vue定義 _drop方法將cartcontrol的傳遞過來target對(duì)象再傳遞給shopCart
  this.$nextTick(() => { // 使用$nextTick優(yōu)化體驗(yàn)
  this.$refs.shopCart.drop(target) // 父組件goods通過.$refs屬性訪問shopCart子組件的drop方法
  })
},
handlecartAdd (target) { // 點(diǎn)擊加號(hào)按鈕觸發(fā)事件
  this._drop(target)  // 調(diào)用_drop方法
}

5. shopCart.vue部分代碼

①.定義一個(gè)數(shù)組,存放5個(gè)小球,這5個(gè)小球可以滿足的動(dòng)畫的運(yùn)行

②.動(dòng)畫分為兩層,外層控制小球y軸方向和運(yùn)動(dòng)的軌道,內(nèi)層控制x軸方向的運(yùn)動(dòng)

③.使用js動(dòng)畫鉤子,vue在實(shí)現(xiàn)動(dòng)畫的時(shí)候提供了幾個(gè)javascript鉤子,可配合css動(dòng)畫一起使用,也可單獨(dú)使用,因?yàn)橘徫镘噿佄锞€小球只有進(jìn)入動(dòng)畫,沒有離開的動(dòng)畫,所以enter的鉤子有,before-enter,enter,after-enter,這些鉤子需要在html屬性中聲明,然后在methods中使用這些方法

可參考以下官網(wǎng)

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> <!--內(nèi)層盒子-->
   </div>
   </transition>
  </div>
  </div>

data

data () {
 return { // 使用balls存放5個(gè)小球,這些小球的默認(rèn)狀態(tài)都是不顯示的
  balls: [{show: false}, {show: false}, {show: false}, {show: false}, {show: false}],
  dropBalls: [] // 用dropBalls來存放掉落的小球
 }
}

在methods中定義方法

// 當(dāng)觸發(fā)drop方法時(shí)小球開始掉落
drop (el) {
  for (let i = 0; i < this.balls.length; i++) { // 遍歷這5個(gè)小球
  let ball = this.balls[i]
  if (!ball.show) { // 當(dāng)小球顯示狀態(tài)為隱藏時(shí)
   ball.show = true // 將這個(gè)小球的顯示狀態(tài)設(shè)置為true
   ball.el = el  // 將cartControl傳過來的對(duì)象掛載到ball的el屬性上
   this.dropBalls.push(ball) // 將這個(gè)小球放入到dropBalls數(shù)組中
   return
  }
  }
}

js動(dòng)畫

// js動(dòng)畫鉤子
// 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()獲取小球相對(duì)于視窗的位置,屏幕左上角坐標(biāo)為0,0
   let x = rect.left - 32 // 小球x方向位移= 小球距離屏幕左側(cè)的距離-外層盒子距離水平的距離
   let y = -(window.innerHeight - rect.top - 22) // 負(fù)數(shù),因?yàn)槭菑淖笊辖窍蛳?
   el.style.display = ''
   el.style.webkitTransform = `translate3d(0,${y}px,0)` // 設(shè)置外層盒子,即小球垂直方向的位移
   el.style.transform = `translate3d(0,${y}px,0)`
   let inner = el.getElementsByClassName('inner-hook')[0]
   inner.style.webkitTransform = `translate3d(${x}px,0,0)` // 設(shè)置內(nèi)層盒子,即小球水平方向的距離
   inner.style.transform = `translate3d(${x}px,0,0)`
  }
  }
},
// enter
handleEnter: function (el, done) {
  /* eslint-disable no-unused-vars */
  // 觸發(fā)瀏覽器重繪
  let rf = el.offsetHeight
  this.$nextTick(() => { // 讓動(dòng)畫效果異步執(zhí)行,提高性能
  el.style.webkitTransform = 'translate3d(0, 0, 0)'// 設(shè)置小球掉落后最終的位置
  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為了知道過渡的完成,必須設(shè)置相應(yīng)的事件監(jiān)聽器。它可以是transitionend或 animationend
  })
},
handleAfterEnter: function (el) {
  let ball = this.dropBalls.shift() // 完成一次動(dòng)畫就刪除一個(gè)dropBalls的小球
  if (ball) {
  ball.show = false
  el.style.display = 'none'
  }
},

希望本文所述對(duì)大家vue.js程序設(shè)計(jì)有所幫助。

相關(guān)文章

最新評(píng)論