【问题标题】:How to animate Vuetify <v-badge /> on state change?如何在状态更改时为 Vuetify <v-badge /> 设置动画?
【发布时间】:2020-05-22 03:53:17
【问题描述】:

在我的导航栏中,我有一个带有&lt;v-badge /&gt; 的“购物车”项目,它显示购物车中有多少项目。当用户添加或删除购物车时,数字会正确地递增和递减。但是,在该数字的状态更改时,我希望能够“反弹”徽章,以向用户提供有关商品已从购物车中添加或删除的反馈。我一直在查看有关动画和过渡的 Vue 文档,但我只是不太了解如何实现这一目标。

我尝试将徽章包装在 &lt;transition /&gt; 元素中并应用我在 CSS Tricks 上找到的一些关键帧动画,但它仍然无法正常工作。

html:

        <v-tabs
          class="hidden-sm-and-down"
          optional>
          <v-tab
            v-for="(item, i) in items"
            :key="i"
            :exact="item.title === 'Home'"
            :to="item.to"
            :ripple="false"
            active-class="text--primary"
            class="font-weight-bold nav-link"
            min-width="96"
            nuxt
            text>
            <transition
              name="ballmove"
              enter-active-class="bouncein"
              leave-active-class="rollout">
              <v-badge
                v-if="item.badge && hasCartItems"
                color="red"
                :content="cartItems"
                :value="cartItems"
                class="default-badge"
                overlap>
                {{ item.title }}
              </v-badge>
              <span v-else>{{ item.title }}</span>
            </transition>
          </v-tab>
        </v-tabs>

scss:

@mixin ballb($yaxis: 0) {
    transform: translate3d(0, $yaxis, 0);
  }

  @keyframes bouncein {
    1% { @include ballb(-400px); }
    20%, 40%, 60%, 80%, 95%, 99%, 100% { @include ballb() }
    30% { @include ballb(-80px); }
    50% { @include ballb(-40px); }
    70% { @include ballb(-30px); }
    90% { @include ballb(-15px); }
    97% { @include ballb(-10px); }
  }

  @keyframes rollout {
    0% { transform: translate3d(0, 300px, 0); }
    100% { transform: translate3d(1000px, 300px, 0); }
  }

  @keyframes ballroll {
    0% { transform: rotate(0); }
    100% { transform: rotate(1000deg); }
  }

  .rollout {
    width: 60px;
    height: 60px;
    animation: rollout 2s cubic-bezier(0.55, 0.085, 0.68, 0.53) both;
    div {
      animation: ballroll 2s cubic-bezier(0.55, 0.085, 0.68, 0.53) both;
    }
  }

  .bouncein {
    animation: bouncein 0.8s cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
  }

  .ballmove-enter {
    @include ballb(-400px);
  }

【问题讨论】:

    标签: css vue.js sass vuetify.js


    【解决方案1】:

    所以我最终选择了一种老派的方式。我取出了&lt;v-badge /&gt; 周围的&lt;transition /&gt; 包装器,然后添加了一个watch 函数:

        watch: {
          cartItems: function(newValue, oldValue) {
            const badge = document.querySelector('.v-badge__badge');
            if (newValue !== oldValue) {
              badge.classList.add('bounce');
              this.delay(500).then(() => {
                badge.classList.remove('bounce');
              });
            }
          }
        },
    

    我的 scss 看起来像:

     @mixin ballb($yaxis: 0) {
        transform: translate3d(0, $yaxis, 0);
      }
    
      @keyframes bouncein {
        0%, 50% { @include ballb(-3px); }
        25%, 75%, 100% { @include ballb() }
      }
    
      .bounce {
        animation: bouncein 500ms cubic-bezier(0.25, 0.46, 0.45, 0.94) both;
      }
    

    这给我正在寻找的徽章带来了一点“震动”,但是如果有人有更原生的 Vue 处理方式,我非常希望看到它。

    【讨论】:

      【解决方案2】:

      在 Vue 2.6.11 中,在 @Bill Criswell 的 this answer 的帮助下,我得到了一些帮助。

      从他的回答中我知道我需要徽章元素上的 :key 来强制重新渲染。其余部分直接来自 Vue.js 示例 here

      <transition name="bounce">
         <v-badge
             :key="item.comments.length"
             v-if="item.comments && item.comments.length > 0"
             >
             <span slot="badge">
                 {{ item.comments.length }}
             </span>
             <v-icon>mdi-comment </v-icon>
          </v-badge>
      </transition>
      

      以及刚刚从上面的 Vue 示例中复制的相关 SCSS:

      .bounce-enter-active {
        animation: bounce-in 0.5s;
      }
      .bounce-leave-active {
        animation: bounce-in 0.5s reverse;
      }
      @keyframes bounce-in {
        0% {
          transform: scale(0);
        }
        50% {
          transform: scale(1.5);
        }
        100% {
          transform: scale(1);
        }
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2021-02-10
        • 2021-07-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多