Vue 3扫码登录轮询同步的核心是主动检查二维码状态并驱动UI与逻辑:用useIntervalFn控制3秒轮询,收到confirmed或expired即停止;状态映射为语义化提示;通过Pinia管理loginStatus并联动全局登录态;连续3次失败则指数退避至10秒并提示重试,60秒未恢复则刷新二维码。

Vue 3 中扫码登录的轮询状态同步,核心是让前端持续检查二维码的实时状态,并根据返回结果驱动 UI 变化和后续逻辑。它不是被动等待,而是主动“问”后端:“这个码扫了没?确认了没?过期了没?”。关键在于轮询节奏、状态映射、自动终止和异常兜底。
轮询机制:用 useIntervalFn 控制频率与生命周期
推荐使用 @vueuse/core 的 useIntervalFn,比手写 setInterval 更安全——能自动绑定组件生命周期,避免组件卸载后仍触发请求。
- 初始间隔设为 3000ms(3秒),符合微信官方建议的轮询节奏,兼顾及时性与服务压力
- 一旦收到
confirmed或expired状态,立即调用pause()停止轮询,防止冗余请求 - 若网络失败或超时,不直接报错,而是记录日志并继续下一轮——扫码过程本就存在弱网场景
状态映射:把后端返回值转成可读 UI 提示
后端通常返回标准状态字段(如 pending / scanned / confirmed / expired),前端需做语义化转换:
-
pending→ “请使用微信扫描二维码” -
scanned→ “已扫码,请在手机上确认登录” -
confirmed→ 触发登录成功流程(存 token、跳转首页、更新 Pinia store) -
expired→ 清空二维码、显示“二维码已失效”,并自动重新请求新码
状态联动:轮询结果驱动全局登录状态
轮询本身只是手段,真正起作用的是它如何更新应用级状态。建议用 Pinia 统一管理:
立即学习“前端免费学习笔记(深入)”;
- 定义一个
authStore,含loginStatus: 'idle' | 'scanning' | 'loggingIn' | 'failed' - 轮询中收到
confirmed后,调用authStore.setLoginSuccess(userInfo),内部自动持久化 token 并触发路由守卫重校验 - 若用户中途关闭页面,下次进入时可通过
authStore.checkLocalToken()快速恢复登录态,避免重复扫码
防抖与降频:避免高频失败导致卡顿
当连续几次轮询返回错误(如 404、502),说明二维码可能已被销毁或服务异常:
- 引入简单计数器,连续 3 次失败后,将轮询间隔从 3s 指数退避至 10s
- 同时在 UI 显示轻量提示:“连接稍慢,正在重试…” 而非弹窗打断用户
- 若 60 秒内仍未恢复,主动调用
refreshQrcode()生成新码,重置整个流程


















