异步组件与 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定义异步组件loadingComponent和errorComponent处理加载状态Suspense优雅地显示加载中/错误状态- 路由懒加载:
component: () => import('./View.vue')
下篇讲 TypeScript 与 Vue 3 的结合。
