账号密码登录
微信安全登录
微信扫描二维码登录

登录后绑定QQ、微信即可实现信息互通

手机验证码登录
找回密码返回
邮箱找回 手机找回
注册账号返回
其他登录方式
分享
  • 收藏
    X
    vue2.0购物车小球过渡动画无效
    21
    0

    学习vue2.0,使用仿饿了么项目练习,其中购物车小球动画没有效果,看了一些其他人得代码,还是没有找到原因.
    下面贴出我的代码,和别人代码得链接

    <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; i++) {
              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: #f00
        .content
          display: flex
          background: #141d27
          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: #141d27
              .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: #80858a
                  &.highlight
                    color: #fff
              .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: #fff
                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: #fff
            .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: #2b333b
              &.enough
                background: #00b43c
                color: #fff
        .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>
    

    调试过三个钩子函数,

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

    钩子函数中dom节点获取没有问题,小球得style也正确设置了, 但是过渡动画没有效果,尝试很久实在不知道原因出现在哪,希望高手帮帮忙.

    下面参考别人github上完整项目代码的链接:
    https://github.com/moxiaojing...

    0
    打赏
    收藏
    点击回答
        全部回答
    • 0
    • 萌系小妹纸i 普通会员 1楼

      在 Vue2.0 中,购物车小球的过渡动画可能无效,这可能是因为在渲染时使用的 transition 属性值错误或者动画不流畅。

      首先,确保你已经正确地引入了相关的动画库。例如,如果你使用的是 vue-chartjs,你可以这样做:

      ```javascript import { Chart } from 'vue-chartjs' import { transition } from '@vue/transition'

      // 更改你的 CSS,例如 const radius = 200 const radius2 = 300

      const options = { scales: { yAxes: [{ ticks: { beginAtZero: true } }] }, animations: { radius: { duration: 3000, easing: 'ease-in-out' }, radius2: { duration: 3000, easing: 'ease-in-out' } } }

      export default { components: { Chart }, data() { return { options: options, radius: radius, radius2: radius2 } }, mounted() { this.renderChart(this.data, this.options) }, methods: { renderChart(data, options) { const chart = new Chart(this.$refs.container, { type: 'bar', data, options }) chart.setOption(options) chart.toPath() } } } ```

      接下来,检查你的 transition 属性值是否正确。例如,如果你使用的是 vue-chartjs,你可以这样做:

      ```javascript import { transition } from '@vue/transition'

      export default { components: { Chart }, data() { return { options: options, radius: radius, radius2: radius2 } }, mounted() { this.renderChart(this.data, this.options) }, methods: { renderChart(data, options) { const chart = new Chart(this.$refs.container, { type: 'bar', data, options }) chart.setOption(options) chart.toPath() }, transition() { const transitionOptions = { duration: 3000, easing: 'ease-in-out' } chart.toPath() chart.toZoom() chart.toPivot() } } } ```

      最后,确保你的过渡动画在实际应用中正常工作。你可以通过在 Vue 实例上测试你的过渡动画来验证这一点。

    更多回答
    扫一扫访问手机版
    • 回到顶部
    • 回到顶部