Vue.js 中用 ref 实现无感刷新 Token 的核心是封装响应式状态单元,通过 ref 管理 token 有效、过期、刷新中三种状态,配合 computed ref、请求拦截器中的 Promise 缓存与 watchEffect 自动更新,实现业务透明、无中断、防并发的刷新机制。

Vue.js 中用 ref 实现无感刷新 Token,核心不是“自动重发请求”,而是让异步 Token 刷新过程对业务组件透明、不打断用户操作、不引发重复请求或状态错乱。 关键在于把 Token 刷新逻辑封装进一个可复用的响应式状态单元,由 ref(配合 onBeforeUnmount 和 watchEffect)协调生命周期与并发控制。
用 ref 封装 Token 刷新状态
定义一个 ref 来承载当前 Token 状态,并区分“有效”、“过期待刷新”、“刷新中”三种情况:
- 不直接暴露原始 token 字符串,而是暴露一个 computed ref 或带 getter 的 reactive 对象,读取时自动触发刷新逻辑
- 内部用 ref({ token: '', status: 'idle' }) 管理状态,status 可为 'valid' | 'expired' | 'refreshing'
- 刷新失败时保留旧 token(若未彻底失效)并延后重试,避免立即登出
拦截请求 + 延迟 resolve 实现“无感”
在 axios 请求拦截器中检查 token 状态,若为 'expired',则:
- 不立即 reject 或跳转登录页,而是调用刷新函数并返回一个 Promise,该 Promise 在刷新成功后 resolve 原始 config
- 同一时刻多个过期请求应共享同一个刷新 Promise(用 refreshPromiseRef 缓存),避免并发刷新
- 刷新成功后更新 ref 状态,并通知所有等待中的请求继续执行
组件内无需手动处理,靠响应式驱动
业务组件通过 const { token } = useAuth() 获取 token,其中 token 是一个 computed ref:
立即学习“前端免费学习笔记(深入)”;
- getter 内部检查状态,若为 'expired' 则触发刷新并 await(但对外仍是同步访问形式)
- 配合 watchEffect 监听 token 变化,自动重新拉取受保护数据(如用户信息)
- 组件卸载前清除 pending 刷新回调(用 onBeforeUnmount 清理副作用),防止内存泄漏或状态污染
错误降级与静默重试策略
无感 ≠ 忽略错误。需设计合理兜底:
- 刷新失败时设置短暂冷却期(如 30s),期间新请求仍用旧 token(若签名未失效)或直接报错
- 连续失败 N 次(如 3 次)后清空 token 并跳转登录页,避免无限循环
- 对非敏感接口(如首页公告)允许 token 过期后仍发起请求,后端返回 401 再触发刷新,减少首屏阻塞


















