VueWaitComponent作りました

はじめに

先日開催されたHTML5勉強会にてkoba04氏のReact Suspenseのデモを拝聴した際に、同じような挙動をvue.jsで作れないかと思い土日で実装してみました。

※Suspenseの実装は全く追ってません。見た目上同じUXを得られる挙動をゴールとして作ってみたものとなります。

vue-wait-component


ネーミングは適当です。
挙動としては利用者が任意でローディング演出を出すタイミングを制御できるコンポーネントです。
利用シーンは通信環境の良い(速い)ユーザーにはローディング演出を省き、悪い(遅い)ユーザーにはローディング演出を出す、といった想定です。

昨日弊社で開催したLT Loversでも発表させていただきました!

使い方

$ npm install vue-wait-component
or
$ yarn add vue-wait-component

ライブラリをパッケージ管理ツールから取得し、利用したいvueコンポーネントのscriptタグ内で読み込んでcomponentsに登録します。

<script>
import { WaitList, WaitImg } from 'vue-wait-component'
export default {
  components: { WaitList, WaitImg }
}
</script>

これでカスタムタグとして利用できるようになりました。

WaitList

propsにPromiseオブジェクトを与えてresolveが返ったタイミングでslotのloadingとloadedを切り替えます。
propsのwaitにはloadingを出すまでの遅延ミリ秒を指定し、その遅延より早くPromiseオブジェクトのresolveが返ればloadingが表示される前にloadedが表示されます。
実装は以下のようになります。

<wait-list
    :wait=200
    :promiseMethod="sample()">
    <p slot="loading">loading</p>
    <div slot="loaded">
        <li v-for="val in data" :key="val.text">
            <p>{{ val.text }}</p>
        </li>
    </div>
</wait-list>
...
<script>
...
methods: {
    sample() {
        return new Promise(resolve => {
            axios.get('/user?ID=12345')
            .then(response => {
                resolve(response);
            })
            .catch(error => {
                reject(error);
            });
        }).then(response => {
            this.data = response;
        });
    },
},
...
</script>

この例ではaxiosのレスポンスが200ms以上かかった場合にだけloading演出を出す実装になっています。
axiosのオブジェクトをそのままreturnしても良いですが、Cacheなどを利用する際はこのようにPromiseオブジェクトに内包し、すでCache済みであればそれをresolveするようにしてあげると良いかと思います。もちろんVuexのactionで同じような実装をしても良いです。

WaitImg

こちらのコンポーネントは事前にsrcに設定されている画像をfetchして、resolveが返ったタイミングで画像を表示させる仕様になっています。
低速回線環境において、画像が断片的に表示されていくのを防ぐのと、画像取得に時間がかかる場合はローディング演出を出すようにする、などを利用シーンとしています。
実装は以下のようになります。

<wait-img
    src="https://~~~.com/~~~.jpg"
    alt="test"
    :width=300
    :wait=100>
    <p slot="loading">loading</p>
</wait-img>

こちらはimgタグとあまり変わらないのではないでしょうか。WiatListと同様にwaitでローディング演出を出すタイミングを遅延させることができます。
遅延の演出はslotのloadingに設定してください。

GitHub.ioにDEMOページを用意していますのでよろしければ体験してみてください。React Suspenseで実現していたものをVueで再現できたかと思います。(細かくは違うかもしれませんがあくまでもUXとして)

弊社アイスタイルでは新規案件やリプレース案件でVue.jsを採用することが多くなっています。
一緒にフロントエンドを開発・改善してくださるメンバーを随時募集しています!

アイスタイルの緑髪担当 元デザイナーの中途4年目です PHPer, JSer 時々Gopher