0Pricing
Frontend Academy · 课时

异步组件与 Suspense

使用 defineAsyncComponent 延迟加载组件,将其包裹在 中,并在组件包加载期间显示备用内容。

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

为什么使用异步组件

按需加载大型或很少使用的组件(例如管理面板、图表库)可以保持初始代码包较小。Vue 的 defineAsyncComponent 会处理动态导入的生命周期。

defineAsyncComponent

传入一个加载器函数,该函数返回一个解析为组件的 promise。Vue 会处理加载、错误和超时。

import { defineAsyncComponent } from 'vue';

const Dashboard = defineAsyncComponent(
  () => import('./Dashboard.vue')
);

// Use it like a normal component:
<template>
  <Dashboard />
</template>

配置异步行为

传入选项对象,以自定义加载界面、错误界面、加载前的延迟时间和超时设置。

const Dashboard = defineAsyncComponent({
  loader: () => import('./Dashboard.vue'),
  loadingComponent: LoadingSpinner,
  errorComponent: ErrorPanel,
  delay: 200,    // ms before showing loading
  timeout: 5000  // ms before showing error
});

打包器代码块拆分

动态导入会在输出中变成独立的代码块。使用 Vite/webpack 的魔法注释来命名并预取代码。

const Dashboard = defineAsyncComponent(
  () => import(/* webpackChunkName: 'dashboard' */ './Dashboard.vue')
);

按路由懒加载

Vue Router 支持直接在路由定义中使用异步组件。

const routes = [
  { path: '/',          component: () => import('./Home.vue') },
  { path: '/dashboard', component: () => import('./Dashboard.vue') },
  { path: '/admin',     component: () => import('./Admin.vue') }
];

Suspense 组件

Vue 的实验性 <Suspense> 会在其组件树中的任何异步依赖处于等待状态时渲染后备界面。

<template>
  <Suspense>
    <template #default>
      <Dashboard />
    </template>
    <template #fallback>
      <LoadingSpinner />
    </template>
  </Suspense>
</template>

异步 setup()

setup() 可以是异步的,Vue 会等待它解析完成后再进行渲染。它可以在 Suspense 中使用。

<!-- AsyncPage.vue -->
<script setup>
import { useUserStore } from '@/stores/user';

const userStore = useUserStore();
await userStore.fetchProfile(); // top-level await
</script>

<!-- Parent uses Suspense to handle the await -->

使用 onErrorCaptured 处理错误

在父组件中使用 onErrorCaptured,以捕获来自异步组件或异步 setup 的错误。

import { onErrorCaptured } from 'vue';

onErrorCaptured((err, instance, info) => {
  console.error('Caught:', err, info);
  return false; // prevent propagation
});

组合使用 Suspense 和错误边界

同时使用 Suspense(负责加载)和用于捕获错误的祖先组件来包装异步组件树。

<template>
  <ErrorBoundary>
    <Suspense>
      <template #default><Dashboard /></template>
      <template #fallback><Spinner /></template>
    </Suspense>
  </ErrorBoundary>
</template>

Suspense 仍处于实验阶段

截至 Vue 3.4,<Suspense> 仍标记为实验性,API 可能会发生变化。异步组件本身(defineAsyncComponent)稳定且可用于生产环境。

何时使用异步组件

适合的候选对象:路由组件、管理/设置面板、按需打开的模态框、大型图表/编辑器。不适合:很小的组件、每个页面都会使用的组件(请采用其他方式进行拆分)。

快速检查

Vue 3 中哪个函数可以将动态导入转换为懒加载组件?

回顾:异步组件与 Suspense

defineAsyncComponent 包装动态导入,以实现懒加载。配置 loadingComponent、errorComponent、延迟时间和超时。打包器会生成独立的代码块。通过 component: () => import('...') 实现按路由懒加载。<Suspense> 会在异步依赖解析期间渲染后备界面(仍处于实验阶段)。带有顶层 await 的异步 setup() 可以在 Suspense 中运行。onErrorCaptured 会捕获异步错误。

常见问题解答

「异步组件与 Suspense」课时是免费的吗?

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

「异步组件与 Suspense」这节课中我会学到什么?

使用 defineAsyncComponent 延迟加载组件,将其包裹在 中,并在组件包加载期间显示备用内容。 你通过在浏览器中直接运行的动手代码来练习 Frontend Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Frontend Academy 需要有经验吗?

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

「异步组件与 Suspense」课时需要多长时间?

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

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

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

此课程中的所有课时

  1. 使用 provide() 和 inject() 实现依赖注入
  2. 异步组件与 Suspense
  3. 自定义指令
  4. 插件系统:app.use()
← 返回 Frontend Academy