spec.md 3.8 KB

全局异步 Loading 锁交互

背景

当前前端存在局部 loading、按钮 :loading、路由进度条和上传组件内部进度等多套异步反馈。不同页面覆盖不一致,用户快速连续点击时仍可能产生重复提交、重复删除、重复导出或重复下发请求。

目标

建立平台级全局 Loading 能力:

  • 所有默认业务请求进入统一全屏遮罩,遮罩期间锁定点击、滚动、键盘等页面交互。
  • 并行请求采用引用计数,所有请求结束后才解除遮罩。
  • 请求成功、业务失败、网络错误、超时、拦截器抛错都必须关闭遮罩。
  • 错误提示必须在遮罩关闭后展示,避免错误弹窗被遮罩覆盖。
  • 路由跳转、页面初始化、分页筛选、弹窗加载、批量处理、导入导出、上传等异步链路统一接入。
  • 保留显式豁免能力,允许文件缩略图、后台静默预取等非用户操作请求不锁全屏。

范围

本批纳入

  • Axios 统一请求实例:requestnoPrefixRequestmockRequest
  • postEncrypt 加密请求:复用 request,无需单独改页面。
  • 路由跳转过程:路由守卫开始/完成/异常接入全局 Loading。
  • Naive NUpload action 文件上传、图片上传:补充统一 Loading 计数。
  • 原生 fetch 的用户触发型下载和 SSE/流式请求:接入同一套 manager。
  • 根组件全屏遮罩:全页面覆盖、禁用滚动和点击。

本批不强制纳入

  • 纯展示型图片 blob 拉取、文件缩略图回显等后台渲染请求默认不锁全屏,避免列表/详情打开时大量缩略图请求造成页面长时间不可操作。
  • WebSocket 收发不纳入本次 Loading 计数,除非后续定义为明确用户触发任务。

设计

全局 Loading Manager

新增 useGlobalLoading,内部维护 active token 列表:

  • startGlobalLoading(options) 返回 token。
  • finishGlobalLoading(token) 按 token 结束。
  • withGlobalLoading(fn, options) 包装 Promise。
  • managedFetch(input, init, options) 包装原生 fetch。
  • resolveRequestLoadingText(config) 根据请求方法和 URL 推导提示文案。
  • skipGlobalLoading/globalLoading === false 显式跳过。
  • globalLoadingText 覆盖默认文案。

Axios 接入

在请求拦截器入口立即 start,避免用户连续点击同一按钮时第二次点击进入。响应成功、业务失败、网络失败、请求拦截失败均 finish

路由接入

路由 beforeEach 开始全局 Loading,afterEach/onError 结束。保留现有 $loadingBar 顶部进度反馈。

上传接入

NUpload action 不经过 Axios,需要在 on-before-upload 校验成功后开始 Loading,在 on-finish/on-error 结束。

原生 fetch 接入

用户触发型 fetch 使用 managedFetch 或手动 token 包裹。SSE 流式生成使用手动 token,完成、错误、取消时结束。

验收标准

  • 快速连续点击按钮时,首个请求开始后出现全屏遮罩并阻止后续点击。
  • 多个接口并行时,任一接口先返回不会提前解除遮罩。
  • 接口失败、超时或业务错误时遮罩关闭,随后展示错误提示。
  • 路由跳转期间展示“页面加载中,请稍候...”,菜单重复点击被遮罩拦截。
  • 文件上传展示“文件上传中,请稍候...”,上传完成/失败后解除。
  • 导出/下载展示“文件导出处理中,请稍候...”或“文件下载处理中,请稍候...”。
  • 前端构建通过。

风险与边界

  • 全局遮罩会改变所有业务请求的交互节奏,局部频繁请求页面可能感觉更“重”。通过 skipGlobalLoading 对后台静默请求做豁免。
  • SSE 流式请求如果全程锁定,用户不能中途操作页面。当前按需求锁定到完成/失败/取消,后续如需取消按钮可设计遮罩内取消能力。