2015-09-04 2 views
2

Я пытаюсь анимировать сортировку списка с помощью Vue.js, но не все элементы анимированы. Ты знаешь почему? И как заставить его работать?Как анимировать сортировку списка с помощью Vue.js

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>

ответ

2

Я считаю, что проблема заключается в том, что только один из элементов, оставшаяся в DOM в процессе сортировки. Остальные три удаляются и повторно вставляются для удовлетворения нового заказа, но в результате они не вызывают анимацию.

Как правило, анимация выполняется с использованием системы перехода Vue (http://vuejs.org/guide/transitions.html). Тем не менее, такая же основная проблема удаления и повторной установки, а не отслеживания состояния позиции, будет происходить с использованием этого метода. Как правило, элементы анимированы независимо от их предыдущих и новых позиций (например, постепенное исчезновение в их прежнем положении и постепенное уменьшение их в новом).

Если вам действительно нужно анимироваться из старой позиции в новую, я думаю, вам нужно будет написать свой собственный Javascript-переход, который запоминает предыдущую позицию каждого элемента перед его удалением и оживляет его до новой позиции когда он вставлен.

Существует пример здесь, который должен быть хорошей отправной точкой: http://vuejs.org/guide/transitions.html#JavaScript_Only_Transitions

Другой вариант не сортировать фильтром и сделать это в JavaScript вместо того, чтобы (так что v-for только делает один раз). Затем ориентировать Bind-стиль против нового параметра индекса на ваши вопросы, как это:

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>

+0

Да, вы правы. У вас есть идея сделать код? –

+0

Хорошо, спасибо, я буду исследовать больше об этом. –

+1

Я добавил пример того, как это сделать без перехода на Javascript. –

Смежные вопросы