主题
Suspense组件
1. 基本概念
1.1 什么是Suspense
Suspense是Vue3新增的内置组件,用于处理异步组件和异步数据加载的场景。它可以在等待异步内容加载完成时显示加载状态。
1.2 主要功能
- 处理异步组件加载
- 协调多个异步依赖
- 提供加载状态管理
- 错误处理机制
2. 基本用法
2.1 基础示例
vue
<template>
<Suspense>
<!-- 默认插槽:异步内容 -->
<template #default>
<async-component />
</template>
<!-- fallback插槽:加载状态 -->
<template #fallback>
<div>Loading...</div>
</template>
</Suspense>
</template>
2.2 异步组件定义
js
// AsyncComponent.vue
export default {
async setup() {
const data = await fetchData()
return { data }
}
}
// 使用defineAsyncComponent
const AsyncComp = defineAsyncComponent(() =>
import('./components/AsyncComponent.vue')
)
3. 高级特性
3.1 多个异步依赖
vue
<template>
<Suspense>
<template #default>
<div>
<async-comp-1 />
<async-comp-2 />
<async-comp-3 />
</div>
</template>
<template #fallback>
<loading-component />
</template>
</Suspense>
</template>
3.2 错误处理
vue
<template>
<Suspense>
<template #default>
<async-component />
</template>
<template #fallback>
<loading-component />
</template>
</Suspense>
</template>
<script>
export default {
errorCaptured(error) {
// 处理加载错误
console.error('Async component error:', error)
return false // 阻止错误继续传播
}
}
</script>
4. 实际应用场景
4.1 数据预加载
vue
<script setup>
async function setupComponent() {
const userPromise = fetchUserData()
const postsPromise = fetchUserPosts()
const [user, posts] = await Promise.all([
userPromise,
postsPromise
])
return { user, posts }
}
</script>
4.2 路由组件
js
// router.js
const routes = [
{
path: '/profile',
component: () => import('./views/UserProfile.vue')
}
]
5. 性能优化
5.1 延迟加载
js
const AsyncComponent = defineAsyncComponent({
loader: () => import('./AsyncComponent.vue'),
delay: 200, // 延迟显示加载状态
timeout: 3000 // 超时时间
})
5.2 缓存策略
vue
<template>
<keep-alive>
<Suspense>
<template #default>
<async-component />
</template>
</Suspense>
</keep-alive>
</template>
6. 最佳实践
6.1 组件设计
js
// 合理的异步组件设计
export default {
async setup() {
// 并行请求数据
const [userData, preferences] = await Promise.all([
fetchUserData(),
fetchUserPreferences()
])
// 数据处理
const processedData = processUserData(userData)
return {
userData: processedData,
preferences
}
}
}
6.2 加载状态处理
vue
<template>
<Suspense>
<template #default>
<async-content />
</template>
<template #fallback>
<div class="loading-container">
<loading-spinner />
<loading-progress :progress="loadingProgress" />
</div>
</template>
</Suspense>
</template>
7. 注意事项
- 避免无限循环的异步依赖
- 合理设置超时时间
- 做好错误处理
- 考虑服务端渲染场景
- 优化加载体验
8. 与其他特性配合
8.1 与Transition配合
vue
<template>
<Transition
enter-active-class="fade-enter-active"
leave-active-class="fade-leave-active"
>
<Suspense>
<!-- 异步内容 -->
</Suspense>
</Transition>
</template>
8.2 与状态管理配合
js
// store.js
export const useLoadingStore = defineStore('loading', {
state: () => ({
isLoading: false,
error: null
}),
actions: {
startLoading() {
this.isLoading = true
},
endLoading() {
this.isLoading = false
}
}
})