※※※ 個別の要素を繊細に制御したい場合はdata属性を持たせるなどの別記事を探して参照した方がよい。この記事は大変大雑把な挙動を実装するためのものです。 ※※※
ユーザー動作(テキストフォームの検索実行や、チェックボックスのチェック挙動)のたびに一覧領域をすべてリフレッシュ→その後アニメーションでふわっと表示させるという表現をしたい。
<transition-group name="fade" tag="div" appear>
<template v-if="items.length">
<article v-for="(item,index) in items" v-bind:key="item.id">
...
</article>
</template>
</transition-group>
しかしVue.jsは再描画をなるべく避ける指向のライブラリであるためか、ユーザー動作の前後で変化のない要素がアニメーションにならない。
色々探しても「一度全部消す」という表現に使えそうなやり方がtransition-groupコンポーネントで見つからない。
必ずしも全ての要素に対してVue.jsのtransitionが走るとは限らないので、Vue.jsのtransitionから一旦離れて考えてみる。素朴なCSSアニメーションで組んでみる。
new Vue({
el: '#app',
data: {
animeFlg : false,
},...
computed: {
items: function() {
let arr = [];
this.animeFlg = true;
...絞り込み処理...
setTimeout(function(){
if(this.animeFlg){
this.animeFlg = false;
}
},500);
return arr;
}
}
});
itemsは算出プロパティなので
1.算出プロパティが走るたびにCSSアニメーション用のフラグをtrueにする
2.returnの直前でsetTimeout()を使い、return後にCSSアニメーション用のフラグをfalseにする
<div :class="{ 'refresh-fade' : animeFlg }">
<template v-if="items.length">
<article v-for="(item,index) in items" v-bind:key="item.id">
...
</article>
</template>
</div>
3.一覧のラッパー要素のクラスをデータバインディングにして、アニメーション用フラグの状態によってクラスを制御する
@keyframes refresh-fade {
0% {
opacity: 0;
}
10% {
opacity: 0;
}
100% {
opacity: 1;
}
}
.refresh-fade {
animation: refresh-fade 1s;
}
4.transitionでもいいが制御しやすいのでanimationで指定
これで全体が一度リフレッシュ→フェードされるように見える。とりあえずは望んだ動作になった。
(せっかくのVue.jsのtransition機能を無下にする仕上がり…)
ただこれだと「もっと見る」ボタンなどを押したときの挙動も全体がリフレッシュされるように見えてしまうので、divを再度transition-groupにし、部分動作の際のVue.jsのtransitionを実装する。詳しくは以下の過去記事を参照。
https://qiita.com/c_nnnnnn/items/900f1f8af53f139df92a
<transition-group tag="div" :class="{ 'refresh-fade' : animeFlg }" :name="showMoreAnimeFlg ? 'cat-fade' : 'cat-no-fade'" @after-enter="deAnimate" @after-leave="deAnimate">
<template v-if="items.length">
<article v-for="(item,index) in items" v-bind:key="item.id">
...
</article>
</template>
</transition-group>
...
methods: {
showMoreItems:function(){//もっと見るボタンに追加されているmethod
...
this.showMoreAnimeFlg = true;
},
deAnimate : function(){//Vueのtransition後に発火するイベント
this.showMoreAnimeFlg = false;
}
}
.cat-fade-enter {
opacity: 0;
}
.cat-fade-enter-to {
opacity: 1;
}
.cat-fade-enter-active{
transition: opacity .5s;
}
5.もっと見るボタンクリック時に部分アニメーション用フラグをtrueにする
6.transition-groupに設定されたnameをデータバインディングにして、部分アニメーション用フラグの状態によってクラスを制御する(アニメーションと非アニメーションの切り替え)
7.JavaScriptフックでVue.jsのtransition後に部分アニメーション用フラグをfalseにする
もっとスマートな方法が多分ある。わかりません。