如何使用Vue.js动画化列表排序 [英] How to animate the sorting of a list with Vue.js

查看:62
本文介绍了如何使用Vue.js动画化列表排序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试使用Vue.js动画化列表的排序方式,但并非所有项目都具有动画效果.你知道为什么吗?以及如何使其工作?

I’m trying to animate the sorting of a list with Vue.js, but not all items are animated. Do you know why? And how to make it work?

new Vue({
  el: '#app',
  data: {
    reverse: 1,
    items: [
      { name: 'Foo' },
      { name: 'Bar' },
      { name: 'Baz' },
      { name: 'Qux' }
    ]
  }
})

.moving-item {
  transition: all 1s ease;
  -webkit-transition: all 1s ease;
}
ul {
  list-style-type: none;
  padding: 0;
  position: relative;
}
li {
  position: absolute;
  border: 1px solid #42b983;
  height: 20px;
  width: 150px;
  padding: 5px;
  margin-bottom: 5px;
  color: #42b983;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.0-alpha.2/vue.min.js"></script>
<div id="app">
  <button on-click="reverse = Math.abs(reverse-1)">
    <span v-if="reverse == 0">△</span>
    <span v-if="reverse == 1">▽</span> Order
  </button>
  <ul>
    <li class="moving-item" v-for="item in items | orderBy 'name' reverse" bind-style="{ top: ($index * 35) + 'px'}">{{ item.name }}</li>
  </ul>  
</div>

推荐答案

我相信问题是排序期间在DOM中仅保留了一个元素.其他三个将被删除并重新插入以满足新的顺序,但是结果是它们没有触发动画.

I believe the problem is that only one of the elements is remaining in the DOM during the sort. The other three are being removed and reinserted to satisfy the new ordering – but as a result they are not triggering an animation.

通常,动画是使用Vue过渡系统( http://vuejs.org/guide/transitions.html ).但是,使用该技术会发生删除和重新插入而不跟踪位置状态的相同基本问题.通常,项目的动画设置不受其先前和新位置的影响(例如,旧位置的淡出和新位置的淡入).

Typically, animation is done using the Vue transition system (http://vuejs.org/guide/transitions.html). However, the same basic problem of deletion and reinsertion not tracking position state will occur using that technique. Usually, items are animated independent of their previous and new positions (like fade-out in their old position and fade-in in their new one).

如果您确实需要从旧的位置动画到新的位置,我想您需要编写自己的Javascript过渡,该过渡要记住每个项目的先前位置,然后再将其动画化为新位置.它已插入.

If you really need to animate from the the old position to the new one, I think you would need to write your own Javascript transition that remembers the previous position of each item before it is removed and animates it to the new position when it is inserted.

这里有一个示例,应该是一个很好的起点: http://vuejs.org/guide/transitions.html#JavaScript_Only_Transitions

There is an example here which should be a good starting point: http://vuejs.org/guide/transitions.html#JavaScript_Only_Transitions

另一个选择是不按过滤器排序,而是使用javascript进行排序(这样, v-for 仅呈现一次).然后将您的绑定样式对准项目上的新索引参数,如下所示:

Another option is to not sort by a filter and do it in javascript instead (so that the v-for only renders once). Then target your bind-style against a new index parameter on your items like this:

new Vue({
  el: '#app',
  data: {
    reverse: 1,
    items: [
      { name: 'Foo', position: 0 },
      { name: 'Bar', position: 1 },
      { name: 'Baz', position: 2 },
      { name: 'Qux', position: 3 }
    ]
  },
  methods: {
    changeOrder: function (event) {
      var self = this;
      self.reverse = self.reverse * -1
      var newItems = self.items.slice().sort(function (a, b) { 
        var result;
        if (a.name < b.name) {
          result = 1
        }
        else if (a.name > b.name) {
          result = -1
        }
        else {
          result = 0
        }
        return result * self.reverse
      })
      newItems.forEach(function (item, index) {
        item.position = index;
      });
    }
  }
})
 

.moving-item {
  transition: all 1s ease;
  -webkit-transition: all 1s ease;
}
ul {
  list-style-type: none;
  padding: 0;
  position: relative;
}
li {
  position: absolute;
  border: 1px solid #42b983;
  height: 20px;
  width: 150px;
  padding: 5px;
  margin-bottom: 5px;
  color: #42b983;
}

<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/1.0.0-alpha.2/vue.min.js"></script>
<div id="app">
  <button on-click="changeOrder">
    <span v-if="reverse == -1">△</span>
    <span v-if="reverse == 1">▽</span> Order
  </button>
  <ul>
    <li class="moving-item" v-for="item in items" bind-style="{ top: (item.position * 35) + 'px'}">{{ item.name }}</li>
  </ul>  
</div>

这篇关于如何使用Vue.js动画化列表排序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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