如何在 Vue 中重置 CSS 动画 [英] How to reset CSS animations in Vue

查看:21
本文介绍了如何在 Vue 中重置 CSS 动画的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个这样的列表:

var v = new Vue({'el' : '#app','数据' : {'列表':[1,2,3,4,5,6,7,8,9,10]},方法: {activateClass($event){$event.target.classList.remove('animate');无效 $event.target.offsetWidth;$event.target.classList.add('animate');},改变随机值(){var randomAmount = Math.round(Math.random() * 12);var randomIndex = Math.floor(Math.random() * this.list.length);Vue.set(this.list, randomIndex, randomAmount)}},安装(){var vm = 这个;设置间隔(函数(){vm.changeRandomValue();}, 500);}})

.animate{动画:淡入 0.5 秒;}@关键帧淡出{0% { 背景:蓝色;}100% { 背景:白色;}}

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.3/vue.min.js"></script><div id="应用程序"><ul><li v-for="列表中的项目" v-html="item" @click="activateClass($event)"></li>

如果你运行上面的代码片段,你会看到如果你点击一个 li 它将使用这个代码:

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

向其添加一次类并播放动画(https://css-技巧.com/restart-css-animation/).太棒了!

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

如何在 changeRandomValue 方法内部使用 activateClass 方法?

我有一些关于在元素上使用事件的想法,所以它会是这样的:

  • 但我认为不存在这样的事情.我也一直在研究观察者,但我不认为这真的是他们的目的.

    我可以获取被点击的元素并找到它引用的数据,但我不知道如何获取已更改的数据,然后找到它的 dom 引用.

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

    解决方案

    一个简单的解决方案是使用 类绑定animationend 事件.
    您还可以以编程方式触发相同的解决方案,如 mounted 事件所示.

    new Vue({el: '#app',数据: {项目: [{编号:1,亮点:假}, {编号:2,亮点:假}]},安装(){//演示程序化突出显示setTimeout(() => {this.items[1].highlight = truesetTimeout(() => {this.items[1].highlight = true}, 1000)}, 1000)},方法: {添加类(项目){item.highlight = true},移除类(项目){item.highlight = false}}})

    p {光标:指针;}.animate {动画:淡入 0.5 秒;}@关键帧淡出{0% {背景:蓝色;}100% {背景:白色;}}

    <script src="https://unpkg.com/vue"></script><div id="应用程序"><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>

    I have a list like this:

    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>

    If you run the above snippet, you'll see that if you click an li it will use this code:

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

    To add a class to it once and play an animation (https://css-tricks.com/restart-css-animation/). Awesome!

    Now, I also have a changeRandomValue() function that selects one element from the list array and change its value.

    How would I use the activateClass method from inside of the changeRandomValue method?

    I've had a few thoughts about using events on the element, so it would be something like:

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

    But I don't think anything like that exists. I have also been looking into watchers but I don't think this is really what they are for.

    I have no problem taking the element that has been clicked and finding the data that it is referencing, but I can't work out how to take the data that has been changed and then find its dom reference.

    The reason I'm not using class bindings is that I need to trigger a reflow. Maybe there is a really easy way to do that with vue, but I'm not aware of it.

    解决方案

    One easy solution would be to use class bindings and the animationend event.
    You can also trigger the same solution programmatically, as shown in the mounted event.

    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>

    这篇关于如何在 Vue 中重置 CSS 动画的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

    查看全文
    登录 关闭
    扫码关注1秒登录
    发送“验证码”获取 | 15天全站免登陆