Vue 3 的 setup 函数不能是 async,需用 ref 管理 loading/error/data 三态,并在 try/catch/finally 中更新;推荐封装 useAsyncRequest 组合式函数,异步操作应放在 onMounted 中执行,非关键数据可延后加载,Suspense 适用于组件级异步加载。

Vue 3 的 setup 函数本身不能是 async,否则会返回 Promise 而非响应式上下文,导致组件无法正常渲染。所以异步错误捕获和加载状态管理,必须靠手动控制响应式变量 + 显式错误处理逻辑来实现,而不是依赖函数签名。
用 ref 管理 loading、error、data 三态
这是最直接、可控的方式:用三个 ref 分别表示请求进行中、出错信息、成功数据。所有状态变更都在 try/catch/finally 块内完成,确保 UI 可及时响应。
-
loading:设为
true开始请求,false在finally中统一关闭,避免遗漏 -
error:在
catch中赋值,内容建议包含可读提示(如“网络异常”)和具体错误来源(如err.response?.status或err.message) -
data:只在
try成功后赋值,不重置为初始值,避免闪退或空状态干扰用户
封装可复用的异步请求组合式函数
把 loading/error/data 逻辑抽成 useAsyncRequest 这类函数,能大幅减少重复代码,也便于统一加拦截器、日志或重试机制。
从零开始编排 SpringBoot+Vue 全栈项目工作流,适用于新建全栈项目或完整脚手架请求,触发后依次调用 product‑spec‑builder(需求调研)等模块。
- 接收一个返回 Promise 的函数(如
axios.get),内部自动管理三态 - 暴露
execute方法供模板调用,也可支持手动触发或参数化调用 - 可选加入防抖、节流、取消上次请求(用
AbortController)等增强能力
避免 setup 内直接 await 导致的生命周期问题
虽然 setup 不能是 async,但有人会误写 await fetchData() —— 这会导致执行阻塞、DOM 尚未挂载就操作数据,引发调度器错误或 Cannot read properties of null。
立即学习“前端免费学习笔记(深入)”;
- 正确做法是把异步调用放在
onMounted钩子中,确保组件已挂载、DOM 可访问 - 如果需要首次渲染就带数据,可用
ref初始化默认值(如空数组、骨架结构),再在onMounted中覆盖 - 对非关键数据(如侧边栏统计),甚至可延后到
requestIdleCallback中发起,提升首屏性能
结合 Suspense 处理组件级异步加载
当整个子组件(比如一个图表、详情页)是异步导入的,用 <suspense></suspense> 比在 setup 里手管更简洁,且天然支持嵌套和统一 fallback。
-
<template></template>放异步组件(如<asyncchart></asyncchart>) -
<template></template>放加载中提示(建议用骨架屏而非简单文字) - 注意:
Suspense不捕获错误,仍需配合errorCaptured或全局app.config.errorHandler处理加载失败

















