vue 路由切换 axios 取消掉请求

310 阅读1分钟

实现思路

  1. 通过 axios 请求拦截器, 往一个全局变量添加请求进去(我是放在 vuex 里面)
  1. axios 有个 CancelToken 方法可以拿到取消请求的函数 cancel, 通过这个函数可以停止请求
  1. 在 vue 全局路由守卫添加, 如果页面跳转, 清空所有请求

vuex 里面的代码

export default {
  namespaced: true,
  state: {
    axiosQueue: []
  },
  mutations: {
    setAxiosPromiseCancelArr: (state, cancel) => {
      state.axiosQueue.push(cancel)
    },
    clearAxiosPromiseCancelArr: (state) => {
      if(state.axiosQueue.length !== 0){
        state.axiosQueue.forEach(e => {
          e && e.f()
        })
        state.axiosQueue = []
      }
    },
    clearCommonAxiosPromiseCancel: (state, index) => {
      console.log(state.axiosQueue, index)
      state.axiosQueue[index].f() // 取消重复请求
      state.axiosQueue.splice(index, 1)
    }
  },
  actions: {

  }
}

axios 配置文件里面的代码

const removeCommonPending = (config) => {
  for (const k in store.state.axiosQueue){
    if(store.state.axiosQueue[k].u === config.url + '&' + config.method){
      store.commit('axiosQueue/clearCommonAxiosPromiseCancel', k)
    }
  }
}
/* 请求拦截器 */
axios.interceptors.request.use(config => {
  removeCommonPending(config)
  config.cancelToken = new axios.CancelToken((cancel) => {
    store.commit('axiosQueue/setAxiosPromiseCancelArr', {u: config.url + '&' + config.method, f: cancel})
  })
  return config
})
/* 在 error 里面写的, 防止报错导致的提示框 */
if(axios.isCancel(error)){
  return new Promise(() => {})
}

在 vue 路由守卫上的代码

router.beforeEach((to, from, next) => { 
  store.commit('axiosQueue/clearAxiosPromiseCancelArr')
});