Pinia Actions 实现全局 Loading 控制的核心是将 loading 状态作为 store 响应式字段,在 action 中自动开关;支持布尔值或对象粒度控制,配合 try/finally 保证重置,组件通过状态绑定驱动 UI。

在 Vue 3 项目中,利用 Pinia Actions 实现全局 Loading 控制,核心思路是:把 loading 状态作为 store 的响应式字段,所有接口请求通过封装后的 action 触发,在 action 内部自动控制 loading 开关,避免在每个组件里手动维护。
定义统一的 Loading 状态管理
在 Pinia store 中声明一个 loading 字段(支持多状态粒度):
- 基础方案:用布尔值
isLoading: boolean表示全局加载中 - 进阶方案:用对象如
loading: { user: false, list: false, detail: false },按业务模块或请求标识独立控制 - 推荐搭配
ref或writableComputed实现派生状态,比如isAnyLoading用于显示全局遮罩
在 Action 中自动包裹请求逻辑
所有 API 调用不直接写在组件中,而是收口到 store 的 action,内部统一处理 loading:
- 进入 action 时,根据传入的 key(如
'login')设置对应 loading 为 true - 使用
try / finally确保无论成功失败都重置 loading - 可配合
async / await或Promise.finally(),例如:
组件中调用与 UI 响应联动
组件只需调用 action,并监听 loading 状态驱动 UI:
- 模板中直接绑定
v-loading="userStore.loading.login"(若用 Element Plus) - 或用
v-if="userStore.isAnyLoading"控制全局 loading 遮罩层 - 按钮禁用、骨架屏切换、下拉刷新 loading 等场景,均从同一 source of truth 读取
- 避免在 setup 中重复声明 loading ref,也不需要 emit loading 事件
扩展:支持请求取消与防重复提交
可在 action 层进一步增强健壮性:
- 结合
AbortController,在 loading 设为 true 时创建 signal,请求中传入并监听中断 - 对相同 key 的请求做节流或排队,例如
if (this.loading[key]) return - 添加 loading 超时机制,比如 10 秒未结束则自动关闭并提示“请求超时”

















