异步组件与 Suspense:处理加载状态

异步组件与 Suspense:处理加载状态

大型应用不需要首屏加载所有组件,异步组件让你按需加载。Suspense 让你优雅地处理加载状态。

异步组件

defineAsyncComponent 定义:

import { defineAsyncComponent } from 'vue'

const AsyncUserList = defineAsyncComponent(() =>
  import('./components/UserList.vue')
)

配合 shallowRef 减少响应式开销:

import { defineAsyncComponent } from 'vue'
import { shallowRef } from 'vue'

const AsyncUserList = shallowRef(null)

AsyncUserList.value = defineAsyncComponent(() =>
  import('./components/UserList.vue')
)

加载与错误状态

import { defineAsyncComponent } from 'vue'

const UserList = defineAsyncComponent({
  loader: () => import('./UserList.vue'),
  loadingComponent: LoadingSpinner,
  errorComponent: ErrorMessage,
  delay: 200,        // 加载前显示 loading 的延迟
  timeout: 3000      // 超时时间
})
选项说明
loader异步加载函数
loadingComponent加载中显示的组件
errorComponent加载失败显示的组件
delay延迟显示 loading
timeout超时时间

Suspense

Suspense 是 Vue 3 内置的组件,让异步组件的加载状态更优雅。

<template>
  <Suspense>
    <template #default>
      <AsyncComponent />
    </template>
    <template #fallback>
      <Loading />
    </template>
  </Suspense>
</template>
  • #default:异步组件
  • #fallback:加载中显示的内容

实战:页面骨架屏

<template>
  <Suspense>
    <template #default>
      <ArticleContent />
    </template>
    <template #fallback>
      <ArticleSkeleton />
    </template>
  </Suspense>
</template>
<!-- ArticleSkeleton.vue -->
<template>
  <div class="skeleton">
    <div class="skeleton-title"></div>
    <div class="skeleton-line"></div>
    <div class="skeleton-line short"></div>
  </div>
</template>

错误处理

Suspense 配合错误边界:

<template>
  <Suspense>
    <template #default>
      <AsyncUserList />
    </template>
    <template #fallback>
      <div v-if="error">加载失败:{{ error.message }}</div>
      <div v-else>加载中...</div>
    </template>
  </Suspense>
</template>

<script setup lang="ts">
const error = ref(null)

onErrorCaptured((err) => {
  error.value = err
  return false // 阻止错误继续传播
})
</script>

路由懒加载

和 Vue Router 配合:

const routes = [
  {
    path: '/user',
    component: () => import('./views/User.vue') // 懒加载
  }
]

访问 /user 时才会加载组件,首屏更快。

总结

  • defineAsyncComponent 定义异步组件
  • loadingComponenterrorComponent 处理加载状态
  • Suspense 优雅地显示加载中/错误状态
  • 路由懒加载:component: () => import('./View.vue')

下篇讲 TypeScript 与 Vue 3 的结合。

最后更新 4/30/2026, 8:57:45 AM