async-components
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseAsync Components
异步组件
Table of Contents
目录
When developing large web applications, performance is paramount. The speed with which a page loads and the responsiveness of its interactive elements can greatly impact user experience. As web applications grow in size and complexity, it can become important to ensure that large bundles of code are loaded only when needed. Enter asynchronous components in Vue.
Components are the fundamental building blocks for constructing the UI. Typically, when we use components, they're automatically loaded and parsed, even if they aren't immediately needed.
When to Use
适用场景
- Use this when components have large bundle sizes and aren't needed on initial page load
- This is helpful for modals, dialogs, or any UI that is conditionally rendered based on user action
- 适用于代码包体积较大、初始页面加载时不需要的组件
- 对模态框、对话框或任何基于用户操作条件渲染的UI非常有帮助
When NOT to Use
不适用场景
- For small components where the async loading overhead (chunk request, parsing) outweighs the bundle savings
- For components that are always visible on initial render — async loading delays their appearance
- When the component is already part of the main chunk and splitting it out wouldn't meaningfully reduce bundle size
- 小型组件:异步加载的开销(分片请求、解析)超过代码包体积减少带来的收益
- 初始渲染时始终可见的组件:异步加载会延迟其展示
- 已属于主代码分片的组件:拆分出去无法有效减小代码包体积
Instructions
操作步骤
- Use with dynamic
defineAsyncComponent()to load components on demandimport() - Provide and
loadingComponentoptions for better user experienceerrorComponent - Combine with to trigger async loading only when the component is actually needed
v-if - Use the and
delayoptions for fine-grained control over loading behaviortimeout
- 使用 配合动态
defineAsyncComponent()实现组件按需加载import() - 配置 和
loadingComponent选项以提升用户体验errorComponent - 结合 仅在组件实际需要时触发异步加载
v-if - 使用 和
delay选项对加载行为进行精细化控制timeout
Details
详细说明
Asynchronous components, on the other hand, allow us to define components in a way that they're loaded and parsed only when they're required or when certain conditions are met.
Assume we had a simple modal component that becomes rendered when a button is clicked from the parent. The component file will only contain template and styles that dictate how the modal appears.
Modal.vuehtml
<template>
<div class="modal-mask">
<div class="modal-container">
<div class="modal-body">
<h3>This is the modal!</h3>
</div>
<div class="modal-footer">
<button class="modal-default-button" @click="$emit('close')">OK</button>
</div>
</div>
</div>
</template>In the parent component, we can render the modal component and a button that when clicked toggles the visibility of the modal component with the help of a reactive boolean value ().
AppshowModalhtml
<template>
<button id="show-modal" @click="showModal = true">Show Modal</button>
<Modal v-if="showModal" :show="showModal" @close="showModal = false" />
</template>
<script setup>
import { ref } from "vue";
import Modal from "./components/Modal.vue";
const showModal = ref(false);
</script>From this example, we can see that the modal component is shown only under a specific circumstance — when the user clicks the button. Despite this, the JavaScript bundle associated with the component is loaded automatically when the entire webpage is loaded even before the modal is made visible.
Show ModalThis is fine for the majority of cases. However, under conditions where the bundle size of the modal is really large and/or the application has a multitude of such components, this can lead to a delayed initial load time. With every added bundle, even if it's related to components that are rarely used, the time it takes for the initial page to load grows.
而异步组件允许我们以一种“仅在需要或满足特定条件时才加载和解析”的方式定义组件。
假设我们有一个简单的模态框组件,当用户点击父组件中的按钮时才会渲染。 组件文件仅包含控制模态框外观的模板和样式。
Modal.vuehtml
<template>
<div class="modal-mask">
<div class="modal-container">
<div class="modal-body">
<h3>This is the modal!</h3>
</div>
<div class="modal-footer">
<button class="modal-default-button" @click="$emit('close')">OK</button>
</div>
</div>
</div>
</template>在父组件 中,我们可以渲染模态框组件,并通过一个响应式布尔值()控制按钮点击时模态框的显示状态。
AppshowModalhtml
<template>
<button id="show-modal" @click="showModal = true">Show Modal</button>
<Modal v-if="showModal" :show="showModal" @close="showModal = false" />
</template>
<script setup>
import { ref } from "vue";
import Modal from "./components/Modal.vue";
const showModal = ref(false);
</script>从这个例子可以看出,模态框组件仅在特定情况下才会显示——当用户点击“Show Modal”按钮时。尽管如此,该组件对应的JavaScript代码包会在整个网页加载时自动加载,甚至早于模态框被展示的时间。
在大多数情况下这没问题,但如果模态框的代码包体积非常大,或者应用中有大量此类组件,就会导致初始加载延迟。每增加一个代码包,即使它关联的组件很少被使用,初始页面加载时间也会增加。
defineAsyncComponent
defineAsyncComponent
This is where Vue allows us to divide an app into smaller chunks by loading components asynchronously with the help of the function.
defineAsyncComponent()js
import { defineAsyncComponent } from "vue";
const AsyncComp = defineAsyncComponent(() => {
return new Promise((resolve, reject) => {
// ...load component from the server
resolve(/* loaded component */);
});
});The function accepts a loader function that returns a Promise that resolves to the imported component. However, instead of defining our async component function like the above, we can leverage dynamic imports to load an ECMAScript module asynchronously.
defineAsyncComponent()js
import { defineAsyncComponent } from "vue";
export const AsyncComp = defineAsyncComponent(() =>
import("./components/MyComponent.vue")
);Let's see this in action for our modal example. We'll create a new file titled :
AsyncModal.jsjs
import { defineAsyncComponent } from "vue";
export const AsyncModal = defineAsyncComponent(() => import("./Modal.vue"));In our parent component, we'll now import and use the asynchronous component in place of the component.
AppAsyncModalModalhtml
<template>
<button id="show-modal" @click="showModal = true">Show Modal</button>
<AsyncModal v-if="showModal" :show="showModal" @close="showModal = false" />
</template>
<script setup>
import { ref } from "vue";
import { AsyncModal } from "./components/AsyncModal";
const showModal = ref(false);
</script>With this small change, our modal component will now be asynchronously loaded! When our application webpage initially loads, the bundle for the component is no longer loaded automatically upon page load. When we click the button to trigger the modal to be shown, the bundle is then asynchronously loaded as the modal component is being rendered.
ModalVue提供了 函数,允许我们通过异步加载组件将应用拆分为更小的代码分片。
defineAsyncComponent()js
import { defineAsyncComponent } from "vue";
const AsyncComp = defineAsyncComponent(() => {
return new Promise((resolve, reject) => {
// ...从服务器加载组件
resolve(/* loaded component */);
});
});defineAsyncComponent()js
import { defineAsyncComponent } from "vue";
export const AsyncComp = defineAsyncComponent(() =>
import("./components/MyComponent.vue")
);让我们在模态框示例中实践这一用法。创建一个新文件 :
AsyncModal.jsjs
import { defineAsyncComponent } from "vue";
export const AsyncModal = defineAsyncComponent(() => import("./Modal.vue"));在父组件 中,我们现在导入并使用 异步组件来替代原来的 组件。
AppAsyncModalModalhtml
<template>
<button id="show-modal" @click="showModal = true">Show Modal</button>
<AsyncModal v-if="showModal" :show="showModal" @close="showModal = false" />
</template>
<script setup>
import { ref } from "vue";
import { AsyncModal } from "./components/AsyncModal";
const showModal = ref(false);
</script>只需这一小改动,我们的模态框组件就可以异步加载了!当应用网页初始加载时, 组件的代码包不再随页面自动加载。当我们点击按钮触发模态框显示时,代码包才会在组件渲染时被异步加载。
ModalLoading and error UI
加载与错误状态UI
With , Vue provides developers with more than just a means of asynchronously loading components. It also offers capabilities to display feedback to users during the loading process and handle any potential errors.
defineAsyncComponent()除了异步加载组件, 还为开发者提供了在加载过程中向用户展示反馈、处理潜在错误的能力。
defineAsyncComponent()loadingComponent
loadingComponent
There may be times we may want to provide visual feedback to users while a component is being fetched. To achieve this, has a option that lets us specify a component to show during the loading phase.
defineAsyncComponent()loadingComponentjs
import { defineAsyncComponent } from "vue";
import Loading from "./Loading.vue";
export const AsyncModal = defineAsyncComponent({
loader: () => import("./Modal.vue"),
loadingComponent: Loading,
});As the modal component becomes asynchronously loaded, the user will now be presented with a message.
Loading...有时我们希望在组件加载过程中向用户提供视觉反馈。为此, 提供了 选项,允许我们指定加载阶段显示的组件。
defineAsyncComponent()loadingComponentjs
import { defineAsyncComponent } from "vue";
import Loading from "./Loading.vue";
export const AsyncModal = defineAsyncComponent({
loader: () => import("./Modal.vue"),
loadingComponent: Loading,
});当模态框组件异步加载时,用户将看到“Loading...”提示信息。
errorComponent
errorComponent
In certain conditions (e.g. poor internet connections), there may be chances that the asynchronous component fails to load. The function offers the option to handle such situations, allowing us to specify a component to be displayed when there's a loading error.
defineAsyncComponent()errorComponentjs
import { defineAsyncComponent } from "vue";
import Loading from "./Loading.vue";
import Error from "./Error.vue";
export const AsyncModal = defineAsyncComponent({
loader: () => import("./Modal.vue"),
loadingComponent: Loading,
errorComponent: Error,
});When the modal component fails to load, the component template will be shown.
ErrorThe function accepts further options like , , , and which provide developers with more granular control over the asynchronous loading behavior and user experience. Be sure to check out the API documentation for more details on these properties.
defineAsyncComponent()delaytimeoutsuspensibleonError()The function can help in breaking down the initial load of a Vue application into manageable chunks by deferring the loading of certain components until they're needed. This can help improve page load times and overall application performance especially when an application has numerous components that have a large bundle size.
defineAsyncComponent()在某些情况下(例如网络连接不佳),异步组件可能加载失败。 函数提供了 选项来处理此类情况,允许我们指定加载错误时显示的组件。
defineAsyncComponent()errorComponentjs
import { defineAsyncComponent } from "vue";
import Loading from "./Loading.vue";
import Error from "./Error.vue";
export const AsyncModal = defineAsyncComponent({
loader: () => import("./Modal.vue"),
loadingComponent: Loading,
errorComponent: Error,
});当模态框组件加载失败时,将显示 组件的模板内容。
ErrordefineAsyncComponent()delaytimeoutsuspensibleonError()defineAsyncComponent()