优先在 created 中发起异步请求,因其在数据响应式初始化后、DOM 挂载前执行,可缩短首屏等待时间、避免白屏;mounted 中发起易导致延迟渲染、keep-alive 下数据不更新及 SSR 不一致;SSR 需配合 serverPrefetch 或 asyncData 确保服务端预取。

在 Vue.js 中,异步请求(如 API 调用)的发起时机直接影响首屏渲染速度和用户体验。若在错误的生命周期钩子中发起请求,容易导致白屏、重复请求、数据丢失或组件未响应等问题。关键在于:**优先在 created 中发请求,避免在 beforeMount 或 mounted 中做首屏关键数据获取;服务端渲染(SSR)场景下需额外处理。
为什么 created 是首选?
created 钩子执行时,实例已完成数据响应式绑定、计算属性、侦听器等初始化,但尚未挂载 DOM。此时发起请求:
- 能尽早触发网络请求,缩短首屏等待时间
- 不会因 DOM 未就绪而阻塞渲染逻辑
- 可配合 v-if 或加载状态控制 UI 展示,避免空白容器
- 在 SSR 中,created 是唯一可安全执行数据预取的客户端/服务端共用钩子(需配合 serverPrefetch)
mounted 中发请求的风险
mounted 执行时 DOM 已挂载,看似“更稳妥”,但实际带来隐患:
- 请求延迟发起,用户看到空容器或骨架屏时间变长 → 白屏感加重
- 若请求返回后才更新响应式数据,可能触发额外的 DOM 更新(尤其含 v-for 或复杂嵌套时)
- 在 keep-alive 场景下,mounted 不会重复执行,导致缓存组件无法刷新数据
- 服务端渲染时,mounted 不会在服务端运行,造成前后端行为不一致
如何避免白屏与提升首屏体验?
单纯选对钩子还不够,需配合状态管理和渲染策略:
立即学习“前端免费学习笔记(深入)”;
- 在 data 中预先定义 loading / error / list 等状态,模板中用 v-if 或 v-show 控制展示逻辑(例如:加载中显示 skeleton,无数据时显示 placeholder)
- 对非关键请求(如埋点、次要推荐),可延至 mounted 或 nextTick 后执行,避免阻塞主流程
- 使用 async setup()(Vue 3)或 onBeforeMount + await(需配合 Suspense)实现更可控的数据等待机制
- 路由级数据预取:在 router.beforeEach 或组件级 beforeRouteEnter 中提前拉取,但注意避免重复请求(可结合缓存或 loading 标记)
SSR 场景下的特别处理
服务端渲染要求首屏数据必须在 HTML 发出前就绪:
- Vue 2:在 created 中调用 store.dispatch 或自定义预取函数,并在服务端入口统一 await 所有 serverPrefetch 钩子
- Vue 3(组合式 API):使用 useAsyncState 或封装 asyncData 函数,在 setup 中调用并导出 __asyncData 供服务端提取
- 务必校验服务端与客户端数据一致性,避免 hydration mismatch(例如用 key 或 ssr: false 跳过部分动态内容)


















