vue 2.5.16
を使用します。

アニメーションしないリストの追加・削除・ソート

最初にアニメーションを使わない簡単なリストの追加・削除・ソート機能をざっくり作成してみます。

  1. <div id="app">
  2. <button v-on:click="addItem">追加</button>
  3. <button v-on:click="removeItem">削除</button>
  4. <button v-on:click="order = order * -1">並び替え</button>
  5. <ul>
  6. <li v-for="item in sortedItems" v-bind:key="item.id">{{ item.name }}</li>
  7. </ul>
  8. </div>
  1. <script src="https://cdn.jsdelivr.net/npm/vue@2.5.16/dist/vue.js"></script>
  2. <script>
  3. new Vue({
  4. el: '#app',
  5. data: {
  6. count: 4,
  7. order: 1,
  8. items: [
  9. { id: 1, name: 'item 1' },
  10. { id: 2, name: 'item 2' },
  11. { id: 3, name: 'item 3' },
  12. { id: 4, name: 'item 4' }
  13. ]
  14. },
  15. methods: {
  16. addItem: function() {
  17. this.count += 1;
  18. this.items.push({
  19. id: this.count,
  20. name: 'item ' + this.count
  21. });
  22. },
  23. removeItem: function() {
  24. this.count -= 1;
  25. this.items.splice(this.count, 1);
  26. },
  27. },
  28. computed: {
  29. sortedItems: function() {
  30. order = this.order;
  31. return this.items.sort(function(a, b){
  32. a = a.id;
  33. b = b.id;
  34. return (a === b ? 0 : a > b ? 1 : -1) * order;
  35. });
  36. }
  37. }
  38. });
  39. </script>

機能的な部分はアニメーションを意識する必要はありませんね。

スライドして追加・削除されるアニメーション

単一要素の場合はtransitionタグで囲みましたが、複数の場合はtransition-groupタグを使います。
ultransition-groupに置き換えて、tag属性にulを指定することで、ulに置きかわります。

  1. <transition-group name="items" tag="ul">
  2. <li v-for="item in sortedItems" v-bind:key="item.id">{{ item.name }}</li>
  3. </transition-group>

最後にCSSです。
enterleaveは変わりませんが、transition-groupの場合、並び替えを行なった際に-moveクラスが追加されますので新たに設定します。

  1. .items-leave-active,
  2. .items-enter-active {
  3. transition: opacity .5s, transform .5s ease;
  4. }
  5. .items-leave-to,
  6. .items-enter {
  7. opacity: 0;
  8. transform: translateX(50px);
  9. }
  10. .items-leave,
  11. .items-enter-to {
  12. opacity: 1;
  13. }
  14. .items-move {
  15. transition: transform .5s;
  16. }