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>
問題は、ソート中に要素の1つだけがDOMに残っていることだと思います。他の3つは、新しい順序を満たすために削除および再挿入されていますが、その結果、アニメーションはトリガーされていません。
通常、アニメーションはVue遷移システム(http://vuejs.org/guide/transitions.html)を使用して行われます。ただし、その手法を使用すると、位置の状態を追跡しない削除と再挿入の同じ基本的な問題が発生します。通常、アイテムは以前の位置と新しい位置に関係なくアニメーション化されます(古い位置でのフェードアウトや新しい位置でのフェードインなど)。
本当に古い位置から新しい位置にアニメーション化する必要がある場合は、削除する前に各アイテムの前の位置を記憶し、挿入時に新しい位置にアニメーション化する独自のJavascriptトランジションを作成する必要があると思います。 。
ここに良い出発点となる例があります:http://vuejs.org/guide/transitions.html#JavaScript_Only_Transitions
別のオプションは、フィルターでソートせず、代わりにjavascriptでソートすることです(v-for
1回だけレンダリングされるように)。次に、次のように、アイテムの新しいインデックスパラメータに対してバインドスタイルをターゲットにします。
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>
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加