suspense 通过识别异步组件和顶层 await 自动协调加载状态。它等待 defineasynccomponent 和 async setup/顶层 await 的子组件,暂停渲染并显示 fallback;不拦截 onmounted 中的请求,需在 setup 中直接 await;错误需子组件内 try/catch 处理。

Suspense 组件本身不直接“捕获”异步请求,而是自动感应并等待子组件树中符合条件的异步依赖——只要这些依赖被 Vue 识别为“可挂起(suspensible)”,它就会统一协调加载状态。
哪些异步操作会被 Suspense 自动等待
Suspense 不关心你写的是 fetch、axios 还是 setTimeout,它只识别两类明确标记为异步依赖的场景:
- 使用
defineAsyncComponent定义的异步组件(如import('./Comp.vue')) - 子组件的
setup()是异步函数,或在<script setup></script>中有顶层await表达式(例如const data = await api.getUser())
只要子组件满足其中任一条件,且未显式设置 suspensible: false,Suspense 就会将其纳入等待队列,暂停渲染整个 #default 插槽,转而显示 #fallback 内容。
子组件必须用 async setup 或顶层 await
如果你希望某个子组件(比如 UserList.vue)的接口请求被 Suspense 感知,它不能只在 onMounted 里发请求——那属于副作用,Suspense 无法拦截。正确做法是:
- 在
<script setup></script>中直接await请求(Vue 会自动将该组件标记为异步依赖) - 确保返回响应数据供模板使用,例如:
const res = await fetch('/api/users');<br>const users = await res.json();
此时父组件只需用 <suspense></suspense> 包裹这个 UserList,无需额外配置或监听。
避免常见干扰:suspensible 和错误处理
某些异步组件可能通过 defineAsyncComponent({ suspensible: false }) 主动退出 Suspense 管理——这会让组件自己控制加载态,父级 Suspense 将忽略它。除非有特殊理由,一般不建议关闭。
错误不会被 Suspense 自动捕获并展示 fallback。如果异步操作失败(如 Promise reject),Vue 会抛出未捕获异常。如需兜底,应在子组件内用 try/catch 处理,或在父组件用 errorCaptured 钩子监听。
多层嵌套时的等待逻辑
Suspense 会递归收集其 #default 插槽下所有子孙节点中的异步依赖。例如:
-
<suspense></suspense>→<dashboard></dashboard>(含<profile></profile>和<stats></stats>) - 若
Profile有顶层 await,Stats是 defineAsyncComponent,则 Suspense 会等两者都 resolve 后才渲染整棵子树
这意味着你不用为每个子组件单独写 loading 状态,一个 Suspense 就能统筹多个异步源头。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











