非同期コンポーネントに対するVueのファーストクラスのサポートは素晴らしいですが、非同期コンポーネントがロードされているとき、またはロードに失敗したときを表示する方法を誰もが知っているわけではありません。 それでは、非同期コンポーネントがロードされるのを待っている間に、エラーを表示する方法やコンポーネントをロードする方法を見てみましょう。

入門

vue-cliwebpack-simpleテンプレートを使用して単純なVueプロジェクトを開始します。

Babelがデフォルトでサポートしていない動的インポート関数を使用するため、プロジェクトをビルドするには、小さなBabelプラグインをすばやく追加する必要があります。

# Yarn
$ yarn add babel-plugin-syntax-dynamic-import -D
# NPM
$ npm install babel-plugin-syntax-dynamic-import --save-dev

先に進み、.babelrcを編集して、そのプラグインをすばやく追加します。

.babelrc
{
  "presets": [
    ["env", { "modules": false }],
    "stage-3"
  ],
  plugins": ["syntax-dynamic-import"]
}

コンポーネントの作成

それでは、App.vueの横に3つの非常に複雑なコンポーネントを作成しましょう。

AsyncComponent.vueは、非同期でロードするものです。

AsyncComponent.vue
<template>
  <p>Ohai! I'm an asynchronously-loaded component!</p>
</template>

AsyncLoadError.vueは、何かがひどくうまくいかなかった場合に表示するものです。

AsyncLoadError.vue
<template>
  <p>Oh noes! I was unable to load the asynchronous component. Cry face. :'(</p>
</template>

AsyncLoading.vueは、AsyncComponent.vueの読み込み中に表示されます。

AsyncLoading.vue
<template>
  <p><em>Loading noises</em></p>
</template>

非同期読み込み

ここで、App.vueで、ユーティリティコンポーネントを通常どおりにロードしますが、AsyncComponent.vueには動的な import()構文を使用します。 この関数は、ネットワーク要求が終了したときに実際のデータで解決されるPromiseを返します。

次に、構成オブジェクトを返す矢印関数を使用してAsyncComponentを登録します。 このオブジェクトは、ロードとエラー状態に使用するコンポーネント、およびコンポーネントがロードに失敗したと見なすまでの待機時間を指定します。

これで、アプリで<async-component></async-component>を使用できるようになります。


<template>
  <div id="app">
    <img src="./assets/logo.png">
    <h1>{{ msg }}</h1>
    <h2>Essential Links</h2>
    <ul>
      <li><a href="https://vuejs.org" target="_blank">Core Docs</a></li>
      <li><a href="https://forum.vuejs.org" target="_blank">Forum</a></li>
      <li><a href="https://chat.vuejs.org" target="_blank">Community Chat</a></li>
      <li><a href="https://twitter.com/vuejs" target="_blank">Twitter</a></li>
    </ul>
    <h2>Ecosystem</h2>
    <ul>
      <li><a href="http://router.vuejs.org/" target="_blank">vue-router</a></li>
      <li><a href="http://vuex.vuejs.org/" target="_blank">vuex</a></li>
      <li><a href="http://vue-loader.vuejs.org/" target="_blank">vue-loader</a></li>
      <li><a href="https://github.com/vuejs/awesome-vue" target="_blank">awesome-vue</a></li>
    </ul>
    
    <async-component></async-component>
  </div>
</template>

<script>
import AsyncLoadError from './AsyncLoadError.vue'
import AsyncLoading from './AsyncLoading.vue'
const AsyncComponent = import('./AsyncComponent.vue')

export default {
  components: {
    AsyncComponent: () => ({
      // The component we want to load.
      component: AsyncComponent,
      // The component to use as a placeholder while the
      // async component is loading.
      loading: AsyncLoading,
      // The component to render instead if there is an error
      // loading the async component.
      error: AsyncLoadError,
      // The delay before the loading component is shown.
      delay: 100,
      // If this timeout is reached, the async component is considered
      // to have failed loading.
      timeout: 3000
    })
  },

  name: 'app',
  data () {
    return {
      msg: 'Welcome to Your Vue.js App'
    }
  }
}
</script>

ブラウザの開発者ツールを開くと、非同期コンポーネントがアプリの他の部分とは異なるファイルからロードされていることに気付くはずです。 何か問題が発生したり、ネットワーク接続が非常に遅い場合を除いて、ロードとエラーの状態に気付くことはおそらくないでしょうが、それらも同様に機能します。

ヒント:非同期コンポーネント構成オブジェクトでtimeout0に設定すると、エラー状態をテストできます。

必要なのはそれだけです!