Vue: Async Components
2022-03-28
0. Intro
基本用法
在大型的应用中,我们可以需要把 app 分解成小块,只在需要的时候从 server 加载一个 component。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
这个 function 会接收一个 loader function,loader function 会返回一个 Promise。
当你从 server 接收到了你的 component definition 时,Promise 的 resolve
callback 会被调用。
我们也可以调用 reject(reason)
来表示加载失败。
Wrapper Component
ES module dynamic import also returns a Promise, so most of the time we will use it in combination with
defineAsyncComponent
.
Vite 和 webpack 之类的 bundler 也支持这种语法,所以我们可以用它来 import Vue SFC:
import { defineAsyncComponent } from 'vue'
const AsyncComp = defineAsyncComponent(() =>
import('./components/MyComponent.vue')
)
上面例子中的 AsyncComp
是一个 wrapper component,只有当 component 在 page 上被渲染时才会调用 loader function。
另外,它(wrapper)会把所有的 props 都传入 inner component,所以我们可以用这个 async wrapper 来替代 original component,同时还能达到 lazy loading 的效果。
Use defineAsyncComponent
when registering a component locally
import { defineAsyncComponent } from 'vue'
export default {
// ...
components: {
AsyncComponent: defineAsyncComponent(() =>
import('./components/AsyncComponent.vue')
)
}
}
1. Loading and Error States
因为我们用了异步操作,所以会有 loading 和 error 的状态,我们可以通过 advanced options 来处理这些 states。
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 component,这个 component 会在 inner component 加载的时候显示(会有默认的 200ms 延迟)。
There is a default 200ms delay before the loading component is shown - this is because on fast networks, an instant loading state may get replaced too fast and end up looking like a flicker.
假如提供了 error component,当 Promise returned by the loader function is rejected 时,会显示 error component。
你也可以定义 timeout,当 request 时间过长时显示 error component。
2. Using with Suspense
异步组件可以跟 <Suspense>
组件一起使用。