Appearance
35.Vue 中异步组件的作用及原理
在大型项目中,我们可能需要拆分应用为更小的块,并仅在需要时再从服务器加载相关组件。主要采用
ES 模块动态导入
配合 Vite 和 Webpack 这样的构建工具实现打包时的代码分割。
Vue2 异步组件的写法
回调写法
js{ components: { "my-component": (resolve, reject) => { setTimeout(function () { resolve({ render(h){ return h('div','hello') }, }); }, 1000); }, }, }
{ components: { "my-component": (resolve, reject) => { setTimeout(function () { resolve({ render(h){ return h('div','hello') }, }); }, 1000); }, }, }
Promise 写法
js{ components: { "my-component": () => import(/* webpackChunkName:"B4" */ "./components/B4.vue"), }, }
{ components: { "my-component": () => import(/* webpackChunkName:"B4" */ "./components/B4.vue"), }, }
对象写法
jsconst AsyncComponent = () => ({ // 需要加载的组件 (应该是一个 `Promise` 对象) component: import("./MyComponent.vue"), // 异步组件加载时使用的组件 loading: LoadingComponent, // 加载失败时使用的组件 error: ErrorComponent, // 展示加载时组件的延时时间。默认值是 200 (毫秒) delay: 200, // 如果提供了超时时间且组件加载也超时了,则使用加载失败时使用的组件。默认值是:`Infinity` timeout: 3000, });
const AsyncComponent = () => ({ // 需要加载的组件 (应该是一个 `Promise` 对象) component: import("./MyComponent.vue"), // 异步组件加载时使用的组件 loading: LoadingComponent, // 加载失败时使用的组件 error: ErrorComponent, // 展示加载时组件的延时时间。默认值是 200 (毫秒) delay: 200, // 如果提供了超时时间且组件加载也超时了,则使用加载失败时使用的组件。默认值是:`Infinity` timeout: 3000, });
异步组件原理
- 默认渲染异步占位符节点
- 组件加载完毕后调用 $forceUpdate 强制更新,渲染加载完毕后的组件。
Vue3 异步组件写法
使用defineAsyncComponent
函数定义异步组件。这个函数接受一个工厂函数,工厂函数可以返回一个 Promise,当 Promise 解析后,组件将被加载并渲染。推荐的做法是将异步组件和 工程化工具 的 code-splitting 功能一起配合使用。
js
import { defineAsyncComponent } from "vue";
const AsyncComponent = defineAsyncComponent(() =>
import("./AsyncComponent.vue")
);
import { defineAsyncComponent } from "vue";
const AsyncComponent = defineAsyncComponent(() =>
import("./AsyncComponent.vue")
);
js
const AsyncComp = defineAsyncComponent({
// 加载函数
loader: () => import("./Foo.vue"),
// 加载异步组件时使用的组件
loadingComponent: LoadingComponent,
// 展示加载组件前的延迟时间,默认为 200ms
delay: 200,
// 加载失败后展示的组件
errorComponent: ErrorComponent,
// 如果提供了一个 timeout 时间限制,并超时了
// 也会显示这里配置的报错组件,默认值是:Infinity
timeout: 3000,
});
const AsyncComp = defineAsyncComponent({
// 加载函数
loader: () => import("./Foo.vue"),
// 加载异步组件时使用的组件
loadingComponent: LoadingComponent,
// 展示加载组件前的延迟时间,默认为 200ms
delay: 200,
// 加载失败后展示的组件
errorComponent: ErrorComponent,
// 如果提供了一个 timeout 时间限制,并超时了
// 也会显示这里配置的报错组件,默认值是:Infinity
timeout: 3000,
});
- 先基于状态,默认渲染异步占位符节点。
- 组件加载完毕后,更新状态,渲染加载完毕的组件。