###### tags: `Vue` # 【Vue】 非同步元件 (Async Components) > 在大型專案中,很常需要將專案切分成小元件,並只在需要時載入來節省效能,Vue 為此提供了 `defineAsyncComponent` 函式。 ```js= 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) 來處理載入失敗 ```js= import { defineAsyncComponent } from 'vue' const AsyncComp = defineAsyncComponent(() => import('./components/MyComponent.vue') ) ``` ES module dynamic import 提供的 import 函式也會回傳 Promise,所以大可直接使用 import。 ## 註冊 和一般的 component 一樣,可以全域註冊或是區域註冊 全域 ```js= app.component('MyComponent', defineAsyncComponent(() => import('./components/MyComponent.vue') )) ``` 區域 ```js= <script setup> import { defineAsyncComponent } from 'vue' const AdminPage = defineAsyncComponent(() => import('./components/AdminPageComponent.vue') ) </script> <template> <AdminPage /> </template> ``` ## 載入與錯誤狀態 一般來說非同步會包含載入中和錯誤的狀態,`defineAsyncComponent()` 也有支援這些狀態 ```js= 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 的單元