vue router 路由切换时应在离开当前页面前主动中止请求,推荐用 abortcontroller + onbeforerouteleave;中大型项目可用全局拦截+路由守卫统一清理;旧版可兼容 canceltoken + vuex;需配合禁用按钮、分页 abort、离开确认及幂等接口提升体验。

Vue Router 在路由切换时取消上一个页面的未完成请求,关键不是“等跳转完成再清理”,而是**在离开当前页面前主动中止所有进行中的请求**。这能防止响应返回后更新已销毁组件、避免内存泄漏、提升性能和用户体验。
用 AbortController + onBeforeRouteLeave(推荐)
这是 Vue 3 + Vue Router 4 的标准做法,原生、可靠、语义清晰:
- 在组件
setup()中创建独立的AbortController实例(每个请求/组件一份,不复用) - 发起请求时(如
axios.get(..., { signal })或fetch(..., { signal })),把controller.signal传入配置 - 使用
onBeforeRouteLeave钩子,在用户即将离开本页面时调用controller.abort() - 错误处理中检查
error.name === 'AbortError',跳过 UI 提示或状态更新
全局拦截 + 路由守卫统一清理(适合中大型项目)
当多个页面都需要自动取消能力,可抽离为基础设施:
分析 Vue 3 Composition API 使用情况——审计响应式模式、可组合函数设计、ref 与 reactive 的选择、计算属性、watcher 使用及组件……
- 在 axios 请求拦截器中为每个请求生成并存储
AbortController,用Symbol()或 URL+method 作为唯一 key 存入 Map - 在
router.beforeEach中遍历该 Map,对所有未完成请求调用abort(),再清空 Map - 在响应/错误拦截器中及时移除已完成请求对应的 controller,避免误删
- 注意:此方式会取消所有 pending 请求,需确认业务是否允许(如后台上传不应被中断)
兼容旧版:CancelToken + Vuex 管理(仅限 Axios
若暂无法升级 Axios 或需兼容老项目,仍可用 CancelToken,但需注意已废弃:
- 在请求拦截器中通过
axios.CancelToken.source()创建 token,并将source.cancel存入 Vuex store 数组 - 在
router.beforeEach中触发store.dispatch('clearAllTokens'),批量执行 cancel 方法 - 响应拦截器中判断
axios.isCancel(error),静默处理,不触发 toast 或 loading 状态变更 - 务必避免在组件内手动调用 cancel——必须绑定到路由守卫,否则用户快速跳转时仍会漏掉
配合交互体验做增强
单纯取消还不够,要让行为更健壮、用户感知更友好:
- 表单提交按钮添加
:disabled="loading",防止重复点击引发多请求竞态 - 分页加载场景下,每次新请求前先 abort 上一次 controller,再新建一个
- 若支持「离开前确认」(如表单未保存),
onBeforeRouteLeave中可先 abort,再弹窗;用户取消跳转则无需恢复请求 - 服务端接口建议增加幂等性设计,即使取消失败、请求最终抵达,也不造成脏数据
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!









