代码之家  ›  专栏  ›  技术社区  ›  Djave

如何在Vue中重置CSS动画

  •  7
  • Djave  · 技术社区  · 8 年前

    我有这样一个列表:

    var v = new Vue({
      'el' : '#app',
      'data' : {
        'list' : [1,2,3,4,5,6,7,8,9,10]
      },
      
      methods: {
        activateClass($event){
          $event.target.classList.remove('animate');
          void $event.target.offsetWidth;
          $event.target.classList.add('animate');
        },
        changeRandomValue(){
          var randomAmount = Math.round(Math.random() * 12);
          var randomIndex = Math.floor(Math.random() * this.list.length);
          Vue.set(this.list, randomIndex, randomAmount)
        }
      },
      
      mounted(){
        var vm = this;
        setInterval(function(){
          vm.changeRandomValue();
        }, 500);
      }
    })
    .animate{
      animation: fade 0.5s;
    }
    
    @keyframes fade{
      0% { background:blue; }
      100% { background:white; }
    }
    <script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script>
    <div id="app">
      <ul>
        <li v-for="item in list" v-html="item" @click="activateClass($event)"></li>
      </ul>
    </div>

    如果运行上述代码段,您将看到,如果单击某个li,它将使用以下代码:

    activateClass($event){
      $event.target.classList.remove('animate');
      void $event.target.offsetWidth;
      $event.target.classList.add('animate');
    }
    

    向其中添加一个类并播放动画( https://css-tricks.com/restart-css-animation/ ). 令人惊叹的

    现在,我还有一个 changeRandomValue() 从列表数组中选择一个元素并更改其值的函数。

    我将如何使用 activateClass 方法 changeRandomValue 方法

    我有一些关于在元素上使用事件的想法,因此应该是这样的:

    <li v-for="item in list" v-html="item"
        @click="activateClass($event)"
        @myValueChanged="activateClass($event)"
    ></li>
    

    我对获取已单击的元素并查找其引用的数据没有问题,但我无法确定如何获取已更改的数据,然后查找其dom引用。

    我不使用类绑定的原因是我需要触发回流。也许有一个非常简单的方法可以用vue做到这一点,但我不知道。

    2 回复  |  直到 6 年前
        1
  •  2
  •   Etheryte    8 年前

    一个简单的解决方案是使用 class bindings the animationend 事件
    您还可以通过编程方式触发相同的解决方案,如 mounted 事件

    new Vue({
      el: '#app',
      data: {
        items: [{
          id: 1,
          highlight: false
        }, {
          id: 2,
          highlight: false
        }]
      },
      mounted() {
        // Demonstrate programmatic highlighting
        setTimeout(() => {
          this.items[1].highlight = true
          setTimeout(() => {
            this.items[1].highlight = true
          }, 1000)
        }, 1000)
      },
      methods: {
        addClass(item) {
          item.highlight = true
        },
        removeClass(item) {
          item.highlight = false
        }
      }
    })
    p {
      cursor: pointer;
    }
    
    .animate {
      animation: fade 0.5s;
    }
    
    @keyframes fade {
      0% {
        background: blue;
      }
      100% {
        background: white;
      }
    }
    <script src="https://unpkg.com/vue"></script>
    
    <div id="app">
      <p v-for="item in items" v-bind:class="{ animate: item.highlight }" v-on:click="addClass(item)" v-on:animationend="removeClass(item)">{{ item.id }}</p>
    </div>
        2
  •  0
  •   Comfort Eagle    4 年前

    类似 @Etheryte 的解决方案,但更短:

    v-on:click="($event) => $event.target.classList.add('my-class')"
    v-on:animationend="($event) => $event.target.classList.remove('my-class')"