|
1 | 1 | # Async Components
|
2 | 2 |
|
3 |
| -In large applications, we may need to divide the app into smaller chunks and only load a component from the server when it's needed. To make that possible, Vue has a `defineAsyncComponent` method: |
| 3 | +In large applications, we may need to divide the app into smaller chunks and only load a component from the server when it's needed. To make that possible, Vue has a [`defineAsyncComponent`](/api/general.html#defineasynccomponent) method: |
4 | 4 |
|
5 | 5 | ```js
|
6 |
| -const { createApp, defineAsyncComponent } = Vue |
| 6 | +const { defineAsyncComponent } = Vue |
7 | 7 |
|
8 |
| -const app = createApp({}) |
9 |
| - |
10 |
| -const AsyncComp = defineAsyncComponent( |
11 |
| - () => |
12 |
| - new Promise((resolve, reject) => { |
13 |
| - resolve({ |
14 |
| - template: '<div>I am async!</div>' |
15 |
| - }) |
16 |
| - }) |
17 |
| -) |
18 |
| - |
19 |
| -app.component('async-example', AsyncComp) |
| 8 | +const AsyncComp = defineAsyncComponent(() => { |
| 9 | + return new Promise((resolve, reject) => { |
| 10 | + // ...load component from server |
| 11 | + resolve(/* loaded component */) |
| 12 | + }) |
| 13 | +}) |
| 14 | +// ... use `AsyncComp` like a normal component |
20 | 15 | ```
|
21 | 16 |
|
22 |
| -As you can see, this method accepts a factory function returning a `Promise`. Promise's `resolve` callback should be called when you have retrieved your component definition from the server. You can also call `reject(reason)` to indicate the load has failed. |
| 17 | +As you can see, this method accepts a loader function that returns a Promise. The Promise's `resolve` callback should be called when you have retrieved your component definition from the server. You can also call `reject(reason)` to indicate the load has failed. |
23 | 18 |
|
24 |
| -You can also return a `Promise` in the factory function, so with Webpack 2 or later and ES2015 syntax you can do: |
| 19 | +[ES module dynamic import](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/import#dynamic_imports) also returns a Promise, so most of the time we will use it in combination with `defineAsyncComponent`. Bundlers like Vite and webpack also support the syntax, so we can use it to import Vue SFCs: |
25 | 20 |
|
26 | 21 | ```js
|
27 | 22 | import { defineAsyncComponent } from 'vue'
|
28 | 23 |
|
29 | 24 | const AsyncComp = defineAsyncComponent(() =>
|
30 |
| - import('./components/AsyncComponent.vue') |
| 25 | + import('./components/MyComponent.vue') |
31 | 26 | )
|
32 |
| - |
33 |
| -app.component('async-component', AsyncComp) |
34 | 27 | ```
|
35 | 28 |
|
| 29 | +The resulting `AsyncComp` is a wrapper component that only calls the loader function when it is actually rendered on the page. In addition, it will pass along any props to the inner component, so you can use the async wrapper to seamlessly replace the original component while achieving lazy loading. |
| 30 | + |
| 31 | +<div class="options-api"> |
| 32 | + |
36 | 33 | You can also use `defineAsyncComponent` when [registering a component locally](/guide/components/registration.html#local-registration):
|
37 | 34 |
|
38 | 35 | ```js
|
39 |
| -import { createApp, defineAsyncComponent } from 'vue' |
| 36 | +import { defineAsyncComponent } from 'vue' |
40 | 37 |
|
41 |
| -createApp({ |
| 38 | +export default { |
42 | 39 | // ...
|
43 | 40 | components: {
|
44 | 41 | AsyncComponent: defineAsyncComponent(() =>
|
45 | 42 | import('./components/AsyncComponent.vue')
|
46 | 43 | )
|
47 | 44 | }
|
48 |
| -}) |
| 45 | +} |
49 | 46 | ```
|
50 | 47 |
|
51 |
| -## Using with Suspense |
| 48 | +</div> |
| 49 | + |
| 50 | +## Loading State |
52 | 51 |
|
53 |
| -Async components are _suspensible_ by default. This means if it has a `<Suspense>` in the parent chain, it will be treated as an async dependency of that `<Suspense>`. In this case, the loading state will be controlled by the `<Suspense>`, and the component's own loading, error, delay and timeout options will be ignored. |
| 52 | +## Error Handling |
54 | 53 |
|
55 |
| -The async component can opt-out of `Suspense` control and let the component always control its own loading state by specifying `suspensible: false` in its options. |
| 54 | +## Using with Suspense |
56 | 55 |
|
57 |
| -You can check the list of available options in the [API Reference](/api/general.html#defineasynccomponent) |
| 56 | +Async components can be used with the `<Suspense>` built-in component. The interaction between `<Suspense>` and async components are documented in the [dedicated chapter for `<Suspense>`](/guide/built-ins/suspense.html). |
0 commit comments