非同期コンテンツをロードするときは、コンテンツがロードされているような印象を与える「スケルトン」UIをユーザーに表示することをお勧めします。 ion-skeleton-textを使用して、Ionic内でこれをどのように処理するかを示しましょう。

Ionicプロジェクトの内部では、従来、CSSまたはサードパーティのライブラリを使用してこれを自分で達成する必要がありました。 ありがたいことに、 Ionic 4.1Hydrogen 内の最新のアップデートにより、スケルトンコンテンツの表示に使用できるion-skeleton-textが提供されます。

IonicVue+スケルトンテキスト

これをVue.jsプロジェクトのコンテキストで見ていきますが、IonicはStencilで構築されているため、基本的な原則はフレームワークに依存しません。

開始するには、マシンにNode.jsがインストールされていることを確認してください。 次に、ターミナルで次を実行します。

$ npm install -g @vue/cli

$ vue create vue-ion-skeleton

> default project setup

$ npm install @ionic/core @ionic/vue

次に、main.js内のプロジェクト内にIonicVueを設定する必要があります。 また、Ionicが必要とする基本的なスタイルを@ionic/coreからインポートします。

main.js
import Vue from 'vue';
import App from './App.vue';
import '@ionic/core/css/core.css';
import '@ionic/core/css/ionic.bundle.css';

import IonicVue from '@ionic/vue';

Vue.use(IonicVue); 

Vue.config.productionTip = false;

new Vue({
  render : (h) => h(App)
}).$mount('#app');

この段階で、App.vue内に必要最低限のIonicアプリケーションを作成することで、すべてが正しく機能することをテストできます。

App.vue
<template>
  <ion-app>
    <ion-header>
      <ion-toolbar color="danger">
        <ion-title>S C A R Y</ion-title>
      </ion-toolbar>
    </ion-header>
    <ion-content>
      <ion-card>
        <img src="https://images.unsplash.com/photo-1513681955987-968b5455d7d7?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=933&q=80"/>
        <ion-card-header>
          <ion-card-subtitle>Spooky, Scary</ion-card-subtitle>
          <ion-card-title>Skeleton</ion-card-title>
        </ion-card-header>
        <ion-card-content>
          Nescio brains an Undead zombies. Sicut malus putrid voodoo horror. Nigh tofth eliv ingdead.
        </ion-card-content>
      </ion-card>
    </ion-content>
  </ion-app>
</template>

<script>

export default {
  name: 'app',
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

Scary, Spooky, Ionics.

ベアボーンアプリケーションを作成したので、ion-skeleton-textの例に移りましょう。

スケルトンUI

たとえば、不気味なtodosを多数ロードしたいとします。それぞれが、さまざまなデータを含むAPIから取得されます。

ユーザーがWiFiの悪い場所にいた場合(たとえば、私が今いるようなコーヒーショップ)、このデータがすぐに表示されることを期待するのは無駄です。

私たちは何をしますか? もちろんskeletonデータを表示!

これをアプリケーション内に実装しましょう。 json-placeholder API を使用してAPIからデータを取得し、データが到着するまでion-skeleton-textをUIバッファーとして使用します。

<template>
  <ion-app>
    <ion-header>
      <ion-toolbar color="danger">
        <ion-title>S C A R Y T O D O S</ion-title>
      </ion-toolbar>
    </ion-header>
    <ion-content>
      <ion-list v-if="todos.length > 0">
        <ion-item v-for="todo in todos" :key="todo.id">
          <ion-label>{{todo.title}}</ion-label>
        </ion-item>
      </ion-list>
      <ion-list v-else>
        <ion-item v-for="i in 20" :key="i">
          <ion-label>
            <ion-skeleton-text animated>
            </ion-skeleton-text>
          </ion-label>
        </ion-item>
      </ion-list>
    </ion-content>
  </ion-app>
</template>

<script>

export default {
  name: 'app',
  data() {
    return {
      todos: []
    }
  },
  created() {
    setTimeout(
      () => (
        this.getDataFromAPI()
        ), 3000)
  },
  methods: {
    async getDataFromAPI() {
      try {
        const req = await fetch('https://jsonplaceholder.typicode.com/todos')
        this.todos = await req.json()
      }
      catch(e) {
        console.error(`Error: ${e}`)
      }
    }
  }
}
</script>

<style>
#app {
  font-family: 'Avenir', Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}

</style>

ここで何が起こっているのかを深く掘り下げてみましょう。

  1. まず、json-placeholderAPIに対してfetch呼び出しを行うことで、todosのリストにアクセスします。 これは、私たちが作成したgetDataFromAPIメソッドを介して行われます。
  2. 次に、setTimeout内のcreatedフック内でgetDataFromAPIメソッドを3秒の遅延で呼び出しています。 これは中速のインターネット接続を反映しており、スケルトンテキストの動作を確認するのに十分な時間を与えてくれます。
  3. v-elseブロック内でion-skeleton-textを使用すると、スケルトンコンポーネントを置換するIonicコンポーネントを使用できるため、元のスタイルと同じくらい維持されます。可能。

注:ion-skeleton-text内のanimated属性を利用して、これを画面上でアニメーション化します。 この記事の後半で、アニメーション化されていない場合の様子を確認できます。

これにより、次の魔法のUIが得られます。

Results of our Ionic Skeleton project

その他の例

ion-skeleton-textコンポーネントの優れている点は、非常に柔軟なことです。 widthスタイル属性を使用して、画面上での外観を変更できます。

ion-skeleton-textに少しランダム性を追加しましょう。

<ion-list v-else>
  <ion-item v-for="i in 20" :key="i">
    <ion-label>
      <ion-skeleton-text :style="`width: ${(80 + Math.random () * Math.floor(240))}px;`">
      </ion-skeleton-text>
    </ion-label>
  </ion-item>
</ion-list>

Results of our Ionic Skeleton project with randomness

概要

多田! 🎉これで、スピナーが意味をなさない場所で素晴らしい「読み込み」UIを作成できます。 これは、コンポーネントのどのようにテキストベースの部分がデータを非同期的にロードして白く見えるかを複製するための優れた方法です。

この記事のソースコードはこちらから入手できます:ソースコード