Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 00c9a98

Browse filesBrowse files
committed
async component
1 parent 9f18645 commit 00c9a98
Copy full SHA for 00c9a98

File tree

Expand file treeCollapse file tree

1 file changed

+118
-0
lines changed
Filter options
Expand file treeCollapse file tree

1 file changed

+118
-0
lines changed
+118Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
- Start Date: 2020-03-25
2+
- Target Major Version: 3.x
3+
- Reference Issues: https://github.com/vuejs/rfcs/pull/28
4+
5+
# Summary
6+
7+
Introduce a dedicated API for defining async components.
8+
9+
# Basic example
10+
11+
```js
12+
import { createAsyncComponent } from "vue"
13+
14+
// simple usage
15+
const AsyncFoo = createAsyncComponent(() => import("./Foo.vue"))
16+
17+
// with options
18+
const AsyncFooWithOptions = createAsyncComponent({
19+
loader: () => import("./Foo.vue"),
20+
loading: LoadingComponent,
21+
error: ErrorComponent,
22+
delay: 200,
23+
timeout: 3000
24+
})
25+
```
26+
27+
# Motivation
28+
29+
Per changes introduced in [RFC-0008: Render Function API Change](https://github.com/vuejs/rfcs/blob/master/active-rfcs/0008-render-function-api-change.md), in Vue 3 plain functions are now treated as functional components. Async components must now be explicitly defined via an API method.
30+
31+
# Detailed design
32+
33+
## Simple Usage
34+
35+
```js
36+
import { createAsyncComponent } from "vue"
37+
38+
// simple usage
39+
const AsyncFoo = createAsyncComponent(() => import("./Foo.vue"))
40+
```
41+
42+
`createAsyncComponent` can accept a loader function that returns a Promise resolving to the actual component.
43+
44+
- If the resolved value is an ES module, the `default` export of the module will automatically be used as the component.
45+
46+
- **Difference from 2.x:** Note that the loader function no longer receives the `resolve` and `reject` arguments like in 2.x - a Promise must always be returned.
47+
48+
For code that relies on custom `resolve` and `reject` in the loader function, the conversion is straightforward:
49+
50+
```js
51+
// before
52+
const Foo = (resolve, reject) => {
53+
/* ... */
54+
}
55+
56+
// after
57+
const Foo = createAsyncComponent(() => new Promise((resolve, reject) => {
58+
/* ... */
59+
}))
60+
```
61+
62+
## Options Usage
63+
64+
```js
65+
import { createAsyncComponent } from "vue"
66+
67+
const AsyncFooWithOptions = createAsyncComponent({
68+
loader: () => import("./Foo.vue"),
69+
loading: LoadingComponent,
70+
error: ErrorComponent,
71+
delay: 100, // default: 200
72+
timeout: 3000, // default: Infinity
73+
suspensible: false // default: true
74+
})
75+
```
76+
77+
Options except `loader` and `suspensible` works exactly the same as in 2.x.
78+
79+
**Difference from 2.x:**
80+
81+
The `component` option is replaced by the new `loader` option, which accepts the same loader function as in the simple usage.
82+
83+
In 2.x, an async component with options is defined as
84+
85+
```ts
86+
() => ({
87+
component: Promise<Component>
88+
// ...other options
89+
})
90+
```
91+
92+
Whereas in 3.x it is now:
93+
94+
```ts
95+
createAsyncComponent({
96+
loader: () => Promise<Component>
97+
// ...other options
98+
})
99+
```
100+
101+
## Using with Suspense
102+
103+
Async component in 3.x 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.
104+
105+
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.
106+
107+
# Adoption strategy
108+
109+
- The syntax conversion is mechanical and can be performed via a codemod. The challenge is in determining which plain functions should be considered async components. Some basic heuristics can be used:
110+
111+
- Arrow functions that returns dynamic `import` call to `.vue` files
112+
- Arrow functions that returns an object with the `component` property being a dynamic `import` call.
113+
114+
Note this may not cover 100% of the existing usage.
115+
116+
- In the compat build, it is possible to check the return value of functional components and warn legacy async components usage. This should cover all Promise-based use cases.
117+
118+
- The only case that cannot be easily detected is 2.x async components using manual `resolve/reject` instead of returning promises. Manual upgrade will be required for such cases but they should be relatively rare.

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.