目次
非同期コンポーネントとは
Vue では、グローバル コンポーネントまたはローカル コンポーネントを登録すると、それらは同期的に「すぐに解決されてロード」されます。これは、プログラムが初期化されるときに、すべてのコンポーネントがネットワーク経由でメモリにダウンロードされ、メモリ内の特定のリソースを占有することを意味します。すべてのコンポーネントをプリロードすると、特にモバイル デバイスで、ページの初期読み込み時間とパフォーマンスが遅くなります。これを回避するために、Vue.js は非同期コンポーネントを提供します。
非同期コンポーネントを使用する理由
非同期コンポーネントはコンポーネントを個別にパッケージ化し、オンデマンドでロードできるため、最初のページのロード時間を短縮し、リソースの無駄を削減できます。ルーティングを操作する必要がある場合、非同期コンポーネントはオンデマンドの読み込みと動的インポートの実現にも役立ちます。これにより、ダイナミックローダーコンポーネントの呼び出し時にルートを切り替えてコンポーネントを実装できるため、アプリケーションのパフォーマンスと応答速度の向上に役立ちます。
非同期コンポーネントを定義する
Vue3 はdefineAsyncComponent()
非同期コンポーネントの定義に使用されます。この API の入力パラメータはコンポーネント オプションを返す関数であり、コンポーネントをインポートするには() => import()
この関数。
defineAsyncComponent メソッドは、Promise を返すload関数を受け取ります。この Promise の解決コールバック メソッドは、コンポーネント定義がサーバーから取得されるときに呼び出される必要があります。また、reject(reason) を呼び出して、ロードが失敗したことを示すこともできます。
import {
defineAsyncComponent } from 'vue'
const AsyncComponent = defineAsyncComponent(() => {
return new Promise((resolve, reject) => {
// ...从服务器获取组件
resolve(/* 获取到的组件 */)
})
})
ES モジュールの動的インポートも Promise を返すため、defineAsyncComponent とともに使用します。Vite や Webpack などのビルド ツールもこの構文をサポートしている (パッケージ化するときにコード分割ポイントとして使用している) ため、これを使用して Vue の単一ファイル コンポーネントをインポートすることもできます。
import {
defineAsyncComponent } from 'vue'
const AsyncComponent = defineAsyncComponent(() =>
import('./components/MyComponent.vue')
)
上記のコードで取得された AsyncComponent は外側でラップされたコンポーネントであり、実際の内部コンポーネントをロードする関数は、ページでレンダリングが必要な場合にのみ呼び出されます。
サンプル コード:
defineAsyncComponent 関数を使用して、コンポーネント オブジェクトを返す非同期コンポーネントを定義します。
import {
defineAsyncComponent } from 'vue'
const AsyncComponent = defineAsyncComponent(() => import('./MyComponent.vue'))
export default {
components: {
AsyncComponent
}
}
非同期コンポーネントは上で定義されており、コンポーネントはcomponents
オブジェクト。
非同期コンポーネントのロードとエラー状態
非同期操作を実行すると、必然的にネットワークの読み込み速度の低下や読み込みエラーが発生します。Vue では、defineAsyncComponent() コンポーネントの設計時にこの状況も考慮されており、2 つの構成項目が用意されています: 非同期読み込み コンポーネントの読み込み時に使用されるコンポーネントloadingComponent
ロードが失敗した後に表示されるコンポーネントerrorComponent
。上記 2 つの構成アイテムとして使用する 2 つのカスタム コンポーネント、LoadingComponent.vue と ErrorComponent.vue を作成する必要があります。サンプル
コードは次のとおりです。
const AsyncComp = defineAsyncComponent({
// 加载函数
loader: () => import('./MyComponent.vue'),
// 加载异步组件时使用的组件
loadingComponent: LoadingComponent,
// 展示加载组件前的延迟时间,默认为 200ms
delay: 200,
// 加载失败后展示的组件
errorComponent: ErrorComponent,
// 如果提供了一个 timeout 时间限制,并超时了
// 也会显示这里配置的报错组件,默认值是:Infinity
timeout: 3000
})
上記のコードは、ページが読み込まれるときに最初に LoadingComponent コンポーネントを読み込みます。読み込みコンポーネントが表示されるまでに、デフォルトの 200 ミリ秒の遅延があります。読み込みが失敗した場合は、ErrorComponent コンポーネントが呼び出されます。また、タイムアウトのタイムアウトも指定でき、リクエストが指定した時間よりも長くかかる場合には、エラー報告コンポーネントも表示されます。
サスペンスでの使用
サスペンスとは何ですか?
Suspense は、非同期コンポーネントの読み込み状況を含むサブコンポーネントの読み込み状況を一元管理できる組み込みコンポーネントです。コンポーネントを非同期的にロードするときにロード状態にすることができ、非同期コンポーネントの作成後にコンポーネントを表示できます。
Suspense コンポーネントには、#default と #fallback の 2 つのスロットがあります。どちらのスロットでも直接の子は 1 つだけ許可されます。
最初のレンダリングでは、Suspense はデフォルトの #default スロットの内容をメモリ内にレンダリングします。このプロセス中に非同期依存関係が発生すると、保留状態になります。一時停止状態の間は、#fallback フォールバック コンテンツが表示されます。発生したすべての非同期依存関係が完了すると、Suspense は完了状態になり、デフォルト スロット #default の内容が表示されます。
最初のレンダリング中に非同期依存関係が見つからない場合、Suspense は直接完了状態に移行します。
Suspense は、完了状態に入った後、デフォルト スロット #default のルート ノードが置き換えられた場合にのみ一時停止状態に戻ります。コンポーネント ツリー内の新しいより深い非同期依存関係により、Suspense がサスペンド状態にフォールバックすることはありません。
フォールバックが発生した場合、#fallback フォールバック コンテンツはすぐには表示されません。代わりに、Suspense は、新しいコンテンツと非同期依存関係が完了するのを待機している間、前の #default スロットのコンテンツを表示します。この動作は、タイムアウト プロパティを介して構成できます。サスペンスは、新しいコンテンツをレンダリングするためにタイムアウトを待った後、#fallback フォールバック コンテンツの表示に切り替わります。タイムアウト値を 0 にすると、#default デフォルト コンテンツを置き換えるときに、#fallback フォールバック コンテンツがすぐに表示されます。
サスペンスイベント
Suspense コンポーネントは、pending、resolve、fallback の 3 つのイベントを起動します。保留イベントは、保留状態になると発生します。デフォルトのスロットが新しいコンテンツのフェッチを完了すると、resolve イベントが発生します。フォールバック イベントは、フォールバック スロットの内容が表示されるときにトリガーされます。
非同期コンポーネントの持続可能な機能
非同期コンポーネントはデフォルトで「一時停止」になっています。これは、コンポーネント関係チェーン上にサスペンションがある場合、この非同期コンポーネントはこのサスペンションの非同期依存関係とみなされます。この場合、読み込み状態は Suspense によって制御され、コンポーネント自体の読み込み、エラー報告、遅延、およびタイムアウトのオプションは無視されます。
非同期コンポーネントは、オプションで suspensible: false を指定して、Suspense によって制御する必要がないことを示し、コンポーネントが常に読み込み状態を自身で制御できるようにすることもできます。
Suspense で非同期コンポーネントを使用するためのサンプル コード
<template>
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<p>loading...</p>
</template>
</Suspense>
</template>
Vue3 の非同期コンポーネントに関する雑談はこれで終わりです。気に入った友達はいいね、フォローして集めてください。