📖 概述
Suspense
是 Vue 3 中的一个内置组件,用于处理异步组件加载和异步数据获取。它提供了优雅的加载状态管理和错误处理机制。
🎯 基本概念
什么是 Suspense?
Suspense
是一个包装组件,可以等待异步组件加载完成,并在加载过程中显示备用内容。它解决了异步组件加载时的用户体验问题。
使用场景
- 🔄 异步组件加载
- 🎨 骨架屏和加载动画
- ⚠️ 错误边界处理
🔧 组件结构
<template>
<Suspense>
<!-- 异步内容 -->
<template #default>
<AsyncComponent />
</template>
<!-- 加载状态 -->
<template #fallback>
<LoadingSpinner />
</template>
</Suspense>
</template>
💻 代码示例
🚀 基础用法
<script setup lang="ts">
import { defineAsyncComponent } from "vue";
// 定义异步组件
const AsyncComponent = defineAsyncComponent(
() => import("./HeavyComponent.vue")
);
</script>
<template>
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<div class="loading">加载中...</div>
</template>
</Suspense>
</template>
🎨 骨架屏加载
<script setup lang="ts">
import { defineAsyncComponent } from "vue";
const UserProfile = defineAsyncComponent(() => import("./UserProfile.vue"));
</script>
<template>
<Suspense>
<template #default>
<UserProfile />
</template>
<template #fallback>
<div class="skeleton">
<div class="skeleton-avatar"></div>
<div class="skeleton-name"></div>
<div class="skeleton-bio"></div>
</div>
</template>
</Suspense>
</template>
⚠️ 错误处理
<script setup lang="ts">
import { defineAsyncComponent } from "vue";
const AsyncComponent = defineAsyncComponent({
loader: () => import("./Component.vue"),
errorComponent: ErrorComponent,
timeout: 3000,
});
</script>
<template>
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<LoadingSpinner />
</template>
</Suspense>
</template>
🔧 高级用法
🔄 嵌套 Suspense
<template>
<Suspense>
<template #default>
<div>
<h1>主内容</h1>
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<div>子组件加载中...</div>
</template>
</Suspense>
</div>
</template>
<template #fallback>
<div>主内容加载中...</div>
</template>
</Suspense>
</template>
🎯 条件渲染
<script setup lang="ts">
import { ref } from "vue";
const showAsync = ref(false);
</script>
<template>
<button @click="showAsync = !showAsync">切换异步组件</button>
<Suspense v-if="showAsync">
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<div>加载中...</div>
</template>
</Suspense>
</template>
⚖️ 与选项式 API 的对比
✅ 组合式 API(推荐)
<script setup lang="ts">
import { defineAsyncComponent } from "vue";
const AsyncComponent = defineAsyncComponent(() => import("./Component.vue"));
</script>
<template>
<Suspense>
<AsyncComponent />
</Suspense>
</template>
🔧 选项式 API
<script>
import { defineAsyncComponent } from "vue";
export default {
components: {
AsyncComponent: defineAsyncComponent(() => import("./Component.vue")),
},
};
</script>
⚠️ 注意事项
🔢 生命周期
Suspense
组件在异步内容加载完成前不会触发mounted
生命周期:
<script setup lang="ts">
import { onMounted } from "vue";
onMounted(() => {
console.log("组件已挂载");
});
</script>
📝 错误边界
Suspense
可以捕获异步组件和异步数据获取的错误:
<script setup lang="ts">
import { onErrorCaptured } from "vue";
onErrorCaptured((error) => {
console.error("捕获到错误:", error);
return false; // 阻止错误继续传播
});
</script>
🛡️ 类型安全
在使用 TypeScript 时,异步组件的类型推断:
const AsyncComponent = defineAsyncComponent<
typeof import("./Component.vue")["default"]
>(() => import("./Component.vue"));
🎯 最佳实践
1️⃣ 合理使用 fallback
提供有意义的加载状态,避免空白页面:
<template>
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<div class="loading-state">
<Spinner />
<p>正在加载内容...</p>
</div>
</template>
</Suspense>
</template>
2️⃣ 错误处理
始终提供错误处理机制:
<script setup lang="ts">
import { onErrorCaptured, ref } from "vue";
const hasError = ref(false);
onErrorCaptured((error) => {
hasError.value = true;
console.error(error);
return false;
});
</script>
<template>
<div v-if="hasError" class="error">加载失败,请重试</div>
<Suspense v-else>
<AsyncComponent />
</Suspense>
</template>
3️⃣ 性能优化
合理使用异步组件,避免过度拆分:
<script setup lang="ts">
// 只对大型组件使用异步加载
const HeavyComponent = defineAsyncComponent(
() => import("./HeavyComponent.vue")
);
// 小型组件直接导入
import LightComponent from "./LightComponent.vue";
</script>
❓ 常见问题
Q: Suspense 是否支持 SSR?
A: Vue 3 的 Suspense 在 SSR 中有一些限制,建议在客户端使用。
Q: 如何处理多个异步组件?
A: 可以在一个 Suspense 中包装多个异步组件,或者使用嵌套的 Suspense。
Q: Suspense 和 v-if 的区别?
A: Suspense 专门处理异步加载,v-if 处理条件渲染。两者可以结合使用。
📝 总结
Suspense
是 Vue 3 中处理异步组件和异步数据获取的强大工具。通过合理使用Suspense
,可以提供更好的用户体验,实现优雅的加载状态管理和错误处理。记住要提供有意义的 fallback 内容,并始终考虑错误处理机制。
原文链接:https://code.ifrontend.net/archives/1074,转载请注明出处。
评论0