Vue2.0 shopping cart ball transition animation is invalid

learn vue2.0, to use the ele.me project exercise, in which the shopping cart ball animation has no effect, read some other people"s code, still can not find the reason.
below post my code, and other people"s code to link

<template>
  <div class="shopcart">
    <div class="content">
      <div class="content-left">
        <div class="logo-wrapper">
          <div class="logo" :class="{"highlight" : totalCount>0}">
            <i class="icon-shopping_cart" :class="{"highlight" : totalCount>0}"></i>
          </div>
          <div class="num" v-show="totalCount>0">{{totalCount}}</div>
        </div>
        <div class="price" :class="{"highlight" : totalCount>0}">{{totalPrice}}</div>
        <div class="desc"> {{deliveryPrice}}</div>
      </div>
      <div class=" content-right">
        <div class="pay" :class="payClass">
          {{payDesc}}
        </div>
      </div>
    </div>
    <div class="ball-container">
      <transition-group name="drop" v-on:before-enter="beforeEnter" v-on:enter="whenenter" v-on:after-enter="afterEnter" v-on:before-leave="beforeLeave"
                        v-on:leave="leave" v-on:after-leave="afterLeave">
      <div class="ball" v-for="(ball, index) in balls" v-show="ball.show" :key="index">
        <div class="inner inner-hook"></div>
      </div>
      </transition-group>

    </div>
  </div>
</template>

<script type="text/ecmascript-6">
  import { bus } from "../../util/bus.js"

  export default {
    props: {
      selectFoods: {
        type: Array,
        default () {
          return [
            {
              price: 0,
              count: 0
            }
          ]
        }
      },
      deliveryPrice: {
        type: Number,
        default: 0
      },
      minPrice: {
        type: Number,
        default: 0
      }
    },
    data () {
      return {
        balls: [
          {
            show: false
          },
          {
            show: false
          },
          {
            show: false
          },
          {
            show: false
          },
          {
            show: false
          },
          {
            show: false
          },
          {
            show: false
          }
        ],
        droppedBalls: []
      }
    },
    created () {
      console.log("created")
      bus.$on("addcart", this.dropBall)
    },
    methods: {
      beforeEnter: function (el) {
        console.log("before enter...\n")
        let count = this.balls.length
        while (count--) {
          let ball = this.balls[count]
          if (ball.show) {
            let rect = ball.el.getBoundingClientRect()
            let x = rect.left - 32
            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)`
          }
        }
      },
      whenenter: function (el, done) {
        /* eslint-disable no-unused-vars */
        console.log("when enter animate---\n")
        let rf = el.offsetHeight
        this.$nextTick(() => {
          el.style.display = ""
          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)"
          done()
        })
      },
      afterEnter: function (el) {
        console.log("after enter animate...\n")
        let ball = this.droppedBalls.shift()
        if (ball) {
          ball.show = false
          el.style.display = "none"
        }
      },
      beforeLeave: function (el) {
        // ...
        console.log("before leave animate...\n")
      },
      leave: function (el, done) {
        // ...
        console.log("leave animate...\n")
        done()
      },
      afterLeave: function (el) {
        // ...
        console.log("after leave animate...\n")
      },
      dropBall (el) {
        console.log("dropBall method,el: " + el)
        for (let i = 0; i < this.balls.length; iPP) {
          let ball = this.balls[i]
          if (!ball.show) {
            ball.show = true
            ball.el = el
            this.droppedBalls.push(ball)
            return
          }
        }
      }
    },
    computed: {
      totalPrice () {
        let total = 0
        this.selectFoods.forEach((food) => {
          total += food.price * food.count
        })
        return total
      },
      totalCount () {
        let count = 0
        this.selectFoods.forEach((food) => {
          count += food.count
        })
        return count
      },
      payDesc () {
        if (this.totalPrice === 0) {
          return `${this.minPrice}`
        } else if (this.totalPrice < this.minPrice) {
          let diff = this.minPrice - this.totalPrice
          return `${diff}`
        } else {
          return ""
        }
      },
      payClass () {
        if (this.totalPrice < this.minPrice) {
          return "not-enough"
        } else {
          return "enough"
        }
      }
    }
  }
</script>

<style lang="stylus" rel="stylesheet/stylus">
  .shopcart
    position: fixed
    left: 0
    bottom: 0
    z-index: 50
    width: 100%
    height: 48px
    background: -sharpf00
    .content
      display: flex
      background: -sharp141d27
      font-size: 0
      height: 100%
      color: rgba(255, 255, 255, 0.4)
      .content-left
        flex: 1
        .logo-wrapper
          display: inline-block
          position: relative
          top: -10px
          margin: 0 12px
          padding: 6px
          width: 56px
          height: 56px
          box-sizing: border-box
          vertical-align: top
          border-radius: 50%
          background: -sharp141d27
          .logo
            width: 100%
            height: 100%
            border-radius: 50%
            background: rgb(43, 52, 60)
            text-align: center
            &.highlight
              background: rgb(0, 160, 220)
            .icon-shopping_cart
              line-height: 44px
              font-size: 24px
              color: -sharp80858a
              &.highlight
                color: -sharpfff
          .num
            position: absolute
            top: 0
            right: 0
            width: 24px
            height: 16px
            line-height: 16px
            text-align: center
            border-radius: 16px
            font-size: 9px
            font-weight: 700
            color: -sharpfff
            background: rgb(240, 20, 20)
            box-shadow: 0 4px 8px 0 rgba(0, 0, 0, 0.4)
        .price
          display: inline-block
          vertical-align: top
          margin-top: 12px
          padding-right: 12px
          line-height: 24px
          box-sizing: border-box
          border-right: 1px solid rgba(255, 255, 255, 0.2)
          font-size: 16px
          font-weight: 700
          &.highlight
            color: -sharpfff
        .desc
          display: inline-block
          vertical-align: top
          margin-top: 12px
          padding-left: 12px
          line-height: 24px
          font-size: 10px
      .content-right
        flex: 0 0 105px
        width: 105px
        .pay
          height: 48px
          line-height: 48px
          text-align: center
          font-size: 12px
          font-weight: 700
          &.not-enough
            background: -sharp2b333b
          &.enough
            background: -sharp00b43c
            color: -sharpfff
    .ball-container
      transition: all 1
      .ball
        position: fixed
        left: 32px
        bottom: 22px
        z-index: 200
        width: 18px
        height: 18px
        border-radius: 50%
        transition: all  1s
        &.drop-enter-to, &.drop-leave-to
          transition all 0.4s
          .inner
            width: 16px
            height: 16px
            border-radius: 50%
            background: rgb(0,160,220)
            transition: all 1s linear

</style>

debugged three hook functions,

beforeEnter: function (el) {
  },
enter: function (el, done) {
    done()
},
afterEnter: function (el) {
},

there is no problem in getting the dom node in the hook function, and the style of the ball is set correctly, but the transition animation has no effect. I really don"t know why it appears for a long time. I hope the master can help.

refer to the link to the complete project code on someone else"s github:
https://github.com/moxiaojing.

Mar.04,2021

change the done () in whenEnter to el.addEventListener ('transitionend',done)


in your css. Ball
transition: all 1s
is not fully drawn


I am even more mysterious that the hook function directly does not respond


check out bold text


Why should el.style.display be written in afterEnter? In theory, isn't it hidden by setting ball.show to false?


ask, have you solved it?

Menu