この記事の実装例はこちらです。
背景
UX向上の観点により、読み込みが遅いもの(特に大きなイメージファイルなど)が存在する場合、先に枠を表示し、ダウンロードできた後本物に置き換える設計は最近増えてきています。そのうち、下の図で示されているようなFacebookのロード画面は好例の一つだと言えるでしょう。
この設計をVue.jsで実装するのはそれほど難しくないでしょう。いくつかのVue.js製のプレスホルダーはすでに公開されている(その一、その二)ため、それらを条件付きレンダリング(Conditional Rendering)と合わせ、ディレクティブv-if
とv-else
を活用するだけで実現可能です。
1 | <placeholder v-if="content === null" /> |
こういう風に実装してもダメとは言えませんが、コンテンツの切り替えにトランザクションが全く存在しないため、唐突の感は免れません。よって、置き換えが発生した際に、フェードイン/フェードアウト効果を追加した方がUX的に優しいと思われます。
トランジションモード
Vue.jsでトランジションを追加するのに、非常に簡単なやり方が存在します。そう、Transition
というラッパーコンポーネントで囲み、CSSで定義する方法です。
1 | <template> |
しかし、これだけでは変な動きが出てきます。一時的にプレスホルダーと本物が同時に画面上に現れるわけです。
理由は単純です。transition
内の子コンポーネントのアニメーションが同時に開始するため、プレスホルダーのフェードアウトアニメーションが再生されている間に、本物のコンポーネントがすでに出てきてしまいました。
これを回避するために、Vue.jsがトランジションモードを用意してくれました。現時点ではout-in
とin-out
2種類が提供されていて、out-in
を利用すれば、コンポーネントAが消失した後、コンポーネントBを出現させることは可能になります。
1 | <template> |
より良い表現を求めて
上記の解決策は悪くないと思いますが、もう少しいい表現ができると思いました。今の場合、トランジション効果は一つずつ再生されるため、所用時間が長くなり、入れ替わる感が感じにくくなっています。その為、やはりフェードアウトとフェードインは同時に行って欲しいですね。となると、トランジションモードの使用を取りやめ、その代わりに、CSSのposition
で二つのコンポーネントの位置を同じところに固定すれば、望んでいた効果が出せるはずです。
1 | <template> |
しかし、見た目は完璧でしょうが、この方法はトランジションモードの方法より扱いにくいはずです。なぜかと言いますと、position: absolute;
の使用によって、コンポーネントらがドキュメントフローから出てしまうので、CSS上で配慮しなければいけないものが増えてしまいます。
まとめ
もっといい方法があるのではないかと思いますが、今回はただの実験なので、これ以上追求しませんでした。一見簡単そうなテーマでしたが、完璧に実現することは意外と難しいということを感じましたね。