Vue 3 异步组件:用 defineAsyncComponent 配合 Suspense 做路由级懒加载

test12026-09-265 次阅读

为什么做组件级懒加载

把首屏不需要的图表、编辑器、富文本等大组件直接静态导入,会让主包体积膨胀,拖慢首次可交互时间。Vue 3 提供的 defineAsyncComponent 可以把组件改成动态导入,配合打包工具自动拆出独立 chunk,需要时再加载。

defineAsyncComponent 基本用法

import { defineAsyncComponent } from 'vue';

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

这样 HeavyChart 在第一次被渲染时才会触发 import(),打包后单独成一个文件。

带加载态与错误态的工厂

异步加载有网络延迟和失败可能,用工厂函数可以挂上 loading 与 error 组件,并控制延迟和超时。

const AsyncEditor = defineAsyncComponent({
  loader: () => import('./Editor.vue'),
  loadingComponent: Spinner,
  errorComponent: LoadError,
  delay: 200,        // 超过 200ms 才显示 loading,避免闪一下
  timeout: 10000     // 10s 还没好就切到 error
});

配合 Suspense 与路由

在路由层面,把每个页面写成动态导入,再用 <Suspense> 包裹 <router-view>,即可统一展示加载占位。

// router 配置
const routes = [
  { path: '/report', component: () => import('./views/Report.vue') },
  { path: '/editor', component: () => import('./views/Editor.vue') }
];

// App.vue
<template>
  <Suspense>
    <template #default>
      <router-view />
    </template>
    <template #fallback>
      <div>页面加载中…</div>
    </template>
  </Suspense>
</template>

实战注意点

  • 异步组件内部若用 await setup() 或 async setup,会被 Suspense 捕获;普通组件用 loader 加载即可。
  • Vite 默认按动态 import() 拆包,无需额外配置,但可对大依赖做 manualChunks 进一步细分。
  • 错误态组件要提供重试入口,单纯报错不利于体验。
  • 不要把首屏核心组件也懒加载,否则会多一次请求反而变慢。
T

test1

文章作者

为什么做组件级懒加载 把首屏不需要的图表、编辑器、富文本等大组件直接静态导入,会让主包体积膨胀,拖慢首次可交互时间。V...

分类
技术
发布时间
2026-09-26
字数
约 1348 字
阅读
5 次