Try   HackMD
tags: Vue

【Vue】 非同步元件 (Async Components)

在大型專案中,很常需要將專案切分成小元件,並只在需要時載入來節省效能,Vue 為此提供了 defineAsyncComponent 函式。

import { defineAsyncComponent } from 'vue' const AsyncComp = defineAsyncComponent(() => { return new Promise((resolve, reject) => { // ...load component from server resolve(/* loaded component */) }) }) // ... use `AsyncComp` like a normal component

這個函式可以接受一個回傳 promise 物件的函式,透過 resolve 來傳遞要載入的元件,也可以用 reject(reason) 來處理載入失敗

import { defineAsyncComponent } from 'vue' const AsyncComp = defineAsyncComponent(() => import('./components/MyComponent.vue') )

ES module dynamic import 提供的 import 函式也會回傳 Promise,所以大可直接使用 import。

註冊

和一般的 component 一樣,可以全域註冊或是區域註冊

全域

app.component('MyComponent', defineAsyncComponent(() => import('./components/MyComponent.vue') ))

區域

<script setup> import { defineAsyncComponent } from 'vue' const AdminPage = defineAsyncComponent(() => import('./components/AdminPageComponent.vue') ) </script> <template> <AdminPage /> </template>

載入與錯誤狀態

一般來說非同步會包含載入中和錯誤的狀態,defineAsyncComponent() 也有支援這些狀態

const AsyncComp = defineAsyncComponent({ // the loader function loader: () => import('./Foo.vue'), // A component to use while the async component is loading loadingComponent: LoadingComponent, // Delay before showing the loading component. Default: 200ms. delay: 200, // A component to use if the load fails errorComponent: ErrorComponent, // The error component will be displayed if a timeout is // provided and exceeded. Default: Infinity. timeout: 3000 })
  • 如果有 loading 元件,主體元件載入完成之前會先顯示 loading 元件,loading 元件載入之前預設有 200 毫秒的延遲,因為要是網路太快可能 loading 元件只顯示一下就沒了。

  • 如果有 error 元件,在 Promise return reject 時他就會顯示,你可以設定 timeout 來避免等待 error 的時間太長。

在 Suspense 中使用

非同步元件可以在 Vue 內建的 Suspense 元件中使用,介紹會留到 Suspense 的單元