vue项目路由跳转后上一页面未完成的接口取消
一、 需求
在路由跳转后,如果上一个页面未完成的接口请求,需要取消掉。
比如: 页面A请求接口A,页面B请求接口B。从页面A跳转到页面B,如果接口A未完成,需要取消掉(尤其是点击过快的情况下,还会出现本地缓存的参数被新页面参数替换的情况)。
二、 实现思路
两种方法可以实现:
1. 使用 cancelToken 取消请求
2. 使用内置的 AbortController 取消请求
两种方法思路基本一致,只是代码编辑方面有点不同;在axios的请求拦截器中收集所有发送的接口,存储在vuex的一个数组中,然后在router.beforeEach中(或点击事件中)监听到路由跳转,就把该数组中的所有未完成的请求取消。
三、 代码实现
1. 在store中创建添加请求到数组中,和把数组中请求清空的方法
const state = {clearPmsArr: [], // 取消请求方法数组
};const mutations = {pushPmsStack(state, payload) {state.clearPmsArr.push(payload.clearPms);},clearPmsStack({ clearPmsArr }) {clearPmsArr.forEach((item) => {// 使用 cancelToken 取消请求// item("路由跳转取消之前页面请求请求");// 使用内置的 AbortController 取消请求item.abort("路由跳转取消之前页面请求请求")});clearPmsArr = [];},
};export default {namespaced: true,state,mutations,
};
2. 在axios的请求拦截器中收集发送的请求,调用store的方法;存入对应需要取消的请求方法;在响应拦截器拦截下来 不抛出错误
// 公司将 Axios 进行了一次封装 自己在请求和响应拦截中写上就好
class HttpService extends HttpLib {// 请求拦截器requestBefore(config) {config = {...config,}// 使用 cancelToken 取消请求// store.commit("pmsStack/pushPmsStack", { clearPms: super.cancel });// 使用内置的 AbortController 取消请求const controller = new AbortController();config.signal = controller.signal;// 存入取消请求的 函数;用于切换页面时取消请求store.commit("pmsStck/pushPmsStack", { clearPms: controller });// ...代码省略return super.requestBefore(config)}// 在响应拦截器拦截下来 不抛出错误responseFailed(error) {if(error.name && error.name === "CanceledError"){// 取消请求的情况下,终端Promise调用链return new Promise(() => {});}return new Promise((resolve, reject) => {super.responseFailed(error).catch((e) => {...})})}
}
3. 在路由跳转前(或方法中)取消请求
store.commit("pmsStack/clearPmsStack")