一、Suspense是什么?
<Suspense>
是 Vue 3 中引入的一个内置组件,用于处理异步组件的加载状态。它允许你在异步组件加载完成之前显示一个备用内容(如加载动画或占位符),从而提升用户体验。
1、<Suspense>
的核心功能
-
处理异步组件:
-
<Suspense>
可以包裹异步组件,并在组件加载完成之前显示备用内容。
-
-
支持多个异步依赖:
-
<Suspense>
可以同时处理多个异步操作(如多个异步组件或异步数据请求),并等待所有异步操作完成后再渲染内容。
-
-
提供加载中和加载完成的状态:
-
通过
#default
插槽显示异步组件的内容。 -
通过
#fallback
插槽显示加载中的备用内容。
-
2、基本用法
1. 包裹异步组件
<template>
<Suspense>
<!-- 默认插槽:显示异步组件 -->
<template #default>
<AsyncComponent />
</template>
<!-- 备用插槽:显示加载中的内容 -->
<template #fallback>
<div>Loading...</div>
</template>
</Suspense>
</template>
<script setup lang="ts">
import { defineAsyncComponent } from 'vue';
// 定义一个异步组件
const AsyncComponent = defineAsyncComponent(() =>
import('./AsyncComponent.vue')
);
</script>
解释:
-
AsyncComponent
是一个异步加载的组件。 -
当
AsyncComponent
加载时,#fallback
插槽的内容(如 "Loading...")会显示。 -
当
AsyncComponent
加载完成后,#default
插槽的内容会替换#fallback
。
2. 结合 async setup
使用
Vue 3 的 setup
函数可以是一个异步函数,<Suspense>
也可以处理这种情况。
<template>
<Suspense>
<template #default>
<UserProfile />
</template>
<template #fallback>
<div>Loading user data...</div>
</template>
</Suspense>
</template>
<script>
import { ref } from 'vue';
const UserProfile = {
async setup() {
const user = ref(null);
// 模拟异步数据请求
const fetchUser = () => {
return new Promise((resolve) => {
setTimeout(() => {
resolve({ name: 'John Doe', age: 30 });
}, 2000);
});
};
user.value = await fetchUser();
return {
user,
};
},
template: `
<div>
<h1>User Profile</h1>
<p>Name: {{ user.name }}</p>
<p>Age: {{ user.age }}</p>
</div>
`,
};
export default {
components: {
UserProfile,
},
};
</script>
解释:
-
UserProfile
组件的setup
函数是异步的,模拟了一个数据请求。 -
在数据加载完成之前,
#fallback
插槽的内容会显示。 -
数据加载完成后,
#default
插槽的内容会渲染。
3、高级用法
1. 处理多个异步依赖
<Suspense>
可以同时处理多个异步操作,并等待所有操作完成后再渲染内容。
<template>
<Suspense>
<template #default>
<div>
<AsyncComponent1 />
<AsyncComponent2 />
</div>
</template>
<template #fallback>
<div>Loading all components...</div>
</template>
</Suspense>
</template>
<script>
import { defineAsyncComponent } from 'vue';
const AsyncComponent1 = defineAsyncComponent(() =>
import('./AsyncComponent1.vue')
);
const AsyncComponent2 = defineAsyncComponent(() =>
import('./AsyncComponent2.vue')
);
export default {
components: {
AsyncComponent1,
AsyncComponent2,
},
};
</script>
解释:
-
<Suspense>
会等待AsyncComponent1
和AsyncComponent2
都加载完成后再渲染内容。
2. 错误处理
<Suspense>
本身不提供错误处理机制,但可以通过 onErrorCaptured
钩子捕获异步组件加载中的错误。
<template>
<Suspense>
<template #default>
<AsyncComponent />
</template>
<template #fallback>
<div>Loading...</div>
</template>
</Suspense>
</template>
<script>
import { defineAsyncComponent, onErrorCaptured } from 'vue';
const AsyncComponent = defineAsyncComponent(() =>
import('./AsyncComponent.vue')
);
export default {
components: {
AsyncComponent,
},
setup() {
onErrorCaptured((error) => {
console.error('Error caught by Suspense:', error);
return false; // 阻止错误继续向上传播
});
},
};
</script>
注意事项:
-
<Suspense>
是实验性功能:-
在 Vue 3 中,
<Suspense>
仍然是一个实验性功能,未来可能会有变化。
-
-
嵌套
<Suspense>
:-
<Suspense>
可以嵌套使用,但需要小心处理加载状态和错误捕获。
-
-
兼容性:
-
<Suspense>
依赖于 Vue 3 的异步组件和setup
函数,确保你的项目使用 Vue 3。
-
总结:
-
<Suspense>
是 Vue 3 中用于处理异步组件加载状态的内置组件。 -
通过
#default
插槽显示异步组件内容,通过#fallback
插槽显示加载中的备用内容。 -
支持多个异步依赖和错误处理,适合用于优化用户体验。
-
虽然功能强大,但仍需注意其实验性状态和兼容性问题。