Vue Academy · 课时

使用 defineAsyncComponent 加载异步组件

defineAsyncComponent()、loadingComponent、errorComponent,以及 delay 和 timeout 选项

第 2 / 4 课13 个步骤

使用 defineAsyncComponent 加载异步组件 是 CoddyKit 上的免费 Vue Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Vue Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Vue Academy 课程共包含 4 节课。

为何使用异步组件

defineAsyncComponent 允许您延迟加载组件——只有在组件首次渲染时才获取它的代码。

这支持路由级和组件级的代码拆分,从而缩小初始代码包并加快首次绘制。

加载函数形式

最简单的用法是传入一个返回动态 import() 的加载函数。构建工具会自动将该导入拆分到独立的分块中。

<script setup>
import { defineAsyncComponent } from 'vue'

const SettingsModal = defineAsyncComponent(() =>
  import('./SettingsModal.vue')
)
</script>

<template>
  <SettingsModal v-if="showSettings" />
</template>

选项对象形式

如需更精细的控制,请传入选项对象。主要字段包括:

  • 加载器 — 动态导入函数
  • loadingComponent — 加载期间显示
  • errorComponent — 加载失败时显示
  • 延迟 / timeout — 时间控制项
import { defineAsyncComponent } from 'vue'
import Loading from './Loading.vue'
import ErrorView from './ErrorView.vue'

const AsyncChart = defineAsyncComponent({
  loader: () => import('./Chart.vue'),
  loadingComponent: Loading,
  errorComponent: ErrorView,
  delay: 200,
  timeout: 5000
})

延迟:避免加载指示器闪现

delay 选项(默认值为 200 毫秒)表示 Vue 在显示 loadingComponent 前等待的时间。如果分块加载速度快于延迟时间,就完全不会显示加载指示器。

设置 delay: 0 可立即显示加载状态。

const AsyncPanel = defineAsyncComponent({
  loader: () => import('./Panel.vue'),
  loadingComponent: Spinner,
  // wait 300ms before showing Spinner
  delay: 300
})

timeout:处理加载过慢

timeout 选项设置最长等待时间。如果加载器未能在 timeout 毫秒内完成解析,就会显示 errorComponent,并记录错误。

默认没有 timeout——加载会无限期等待。

const AsyncReport = defineAsyncComponent({
  loader: () => import('./Report.vue'),
  errorComponent: ErrorView,
  // fail if not loaded within 10s
  timeout: 10000
})

onError 回调

onError 处理程序会在加载器被拒绝时运行。它会接收错误、重试函数、失败函数以及当前的尝试次数。

您可以在这里实现带次数限制的重试逻辑,以应对不稳定的网络。

const AsyncWidget = defineAsyncComponent({
  loader: () => import('./Widget.vue'),
  onError(error, retry, fail, attempts) {
    if (attempts <= 3) {
      retry()   // try loading again
    } else {
      fail()    // give up, show errorComponent
    }
  }
})

重试与失败的决策

在 onError 中,您必须准确调用 retry() 或 fail() 其中之一(两者都不调用也会失败)。一种常见策略是对网络错误重试几次,但对于重试无法修复的语法错误或分块错误,则立即失败。

onError(error, retry, fail, attempts) {
  const isNetwork = /Loading chunk/.test(error.message)
  if (isNetwork && attempts <= 2) {
    retry()
  } else {
    fail()
  }
}

与异步挂起配合使用

当异步组件位于 Suspense 边界内时,边界会改为控制加载状态。在这种情况下,组件自己的 loadingComponent 会被忽略,由异步挂起的后备内容优先显示。

<template>
  <Suspense>
    <AsyncChart />  <!-- loadingComponent ignored here -->
    <template #fallback>Loading chart...</template>
  </Suspense>
</template>

为调试命名分块

您可以使用魔法注释为生成的分块命名。这样可以更容易地阅读网络请求和代码包报告。

const AsyncEditor = defineAsyncComponent(() =>
  import(
    /* webpackChunkName: "editor" */
    './RichTextEditor.vue'
  )
)

异步组件与属性

异步组件与普通组件完全一样,可以接收属性并发出事件。一旦真实组件完成解析,Vue 就会透明地转发所有内容——您无需更改调用位置。

<template>
  <AsyncProfile
    :user-id="id"
    @save="handleSave"
  />
</template>

<!-- AsyncProfile resolves to the real component, props/events pass through -->

最佳实践:谨慎延迟加载首屏以下内容

请延迟加载屏幕外的组件、位于交互之后的组件(模态框、选项卡),或很少使用的组件。请避免延迟加载关键的首屏界面——额外的网络往返可能会损害用户感知的性能。

// Good candidate: modal only opened on click
const Modal = defineAsyncComponent(() => import('./Modal.vue'))

// Poor candidate: hero shown immediately on load
// import Hero directly instead

快速检查

检验您对 defineAsyncComponent 的理解。

回顾

您已经学习了使用 defineAsyncComponent 加载异步组件:

  • 加载器形式返回动态 import(),用于代码拆分
  • 选项形式增加了 loadingComponent、errorComponent、delay 和 timeout
  • delay 可避免加载指示器闪现;timeout 会使加载过慢的操作失败
  • onError(error, retry, fail, attempts) 实现重试或失败逻辑
  • 在异步挂起内部,边界的后备内容会接管加载界面
免费开始

用 AI 导师学习 HTML — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
42
课程
156

常见问题解答

「使用 defineAsyncComponent 加载异步组件」课时是免费的吗?

是的 — 「使用 defineAsyncComponent 加载异步组件」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Vue Academy 课程的其余内容,请升级到 CoddyKit PRO。 Vue Academy 课程共包含 4 节课。

「使用 defineAsyncComponent 加载异步组件」这节课中我会学到什么?

defineAsyncComponent()、loadingComponent、errorComponent,以及 delay 和 timeout 选项 你通过在浏览器中直接运行的动手代码来练习 Vue Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Vue Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Vue Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「使用 defineAsyncComponent 加载异步组件」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Vue Academy 课中编写并运行代码吗?

能。每节 Vue Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. Vue Suspense 组件
  2. 使用 defineAsyncComponent 加载异步组件
  3. 使用 renderToWebStream 实现流式 SSR
  4. 延迟 Hydration 策略
← 返回 Vue Academy