封装一下axios

695 阅读2分钟

学习一下如何封装axios

第一步:引入axios

import axios from 'axios 

第二步:创建axios实例并设置请求头

const service = axios.create({
    baseURL: process.env.VUE_APP_BASE_API,  //区分环境
    timeout: 50000
});

第三步:request拦截器

service.interceptors.request.use(
    config => {
        //如果需要取消请求,可以添加这个
        //config.cancelToken = new CancelToken((cancel) => {
        //    CancelStore._axiosPromiseCancel.push(cancel);
        //});
    
    
        if (store.getters.token) {
        //让每个请求携带上自定义签名
            config.headers['Authorization'] = 'xxx' + store.getters.token;
        }
        return config;
    },
    error => {
        MessageBox(error);
        return Promise.reject(error);
    }
);

第四步:设置response拦截器

service.interceptors.response.use(
    (response) => {
        const res = response.data;
        if (res.code === 200) {
            return response.data;
        } else if (res.code === 407) {
            console.log("Token失效,跳转至登陆页面");
        } else {
            Message({
                masssage: res.message,
                type: error,
            });
            return Promise.reject("error");
        }
    },
    error => {
        console.log(error);
        Message({
            message: error.message,
            type: 'error'
        })
        return Promise.reject(error)
    }
);

第五步:暴露出去

export default service

如何让取消一个或多个请求

import axios from 'axios';
window.axiosCancel = [];  //定义一个存放取消请求得标识
service.interceptors.request.use(config => {
    return config
    config.cancelToken = new axios.CancelToken(cancel => {
        window.axiosCancel.push({
            cancel
        })
    })
});
//请求后返回数据拦截
service.interceptors.response.use(res => {
}, (res) => {
    return Promise.reject(res)
})

在组件中使用,发送一个新的请求之前,取消前面的所有正在请求的请求

methods: {

    cancel(){ // 设置一个函数,在执行请求前先执行这个函数
        // 获取缓存的 请求取消标识 数组,取消所有关联的请求
        let cancelArr = window.axiosCancel;
        cancelArr.forEach((ele, index) => {
            ele.cancel("取消了请求") // 在失败函数中返回这里自定义的错误信息
            delete window.axiosCancel[index]
        })
    },
    getList(){
        this.cancel()   // 取消所有正在发送请求的请求
        axios.post(..)  // 发送一个新的请求
    }
}

如果不希望每个组件里面都定义一个cancel函数,我们可以把这个函数挂载到vue实例的原型上,这样就可以在任何组件中使用cancel函数了:this.cancel() ,如下main.js文件中:

import Vue from 'vue'
import App from './App'
import router from './router'
import store from './store'//引入store
Vue.config.productionTip = false
 
// 将cancel,挂载到vue原型上
Vue.prototype.cancel = function(){
    // 获取缓存的 请求取消标识 数组,取消所有关联的请求
    let cancelArr = window.axiosCancel;
    cancelArr = cancelArr || [];
    cancelArr.forEach((ele, index) => {
        ele.cancel("取消了请求")  // 在失败函数中返回这里自定义的错误信息
        delete window.axiosCancel[index]
    })
}
 
window.vm=new Vue({
  el: '#app',
  data(){
    return{
    }
  },
  router,
  store,
  components: { App },
})

另外如果想每次路由页面跳转时,取消上一个页面的所有请求,我们可以把cancel()函数的内容放在路由拦截器中,router/index.js文件配置,如下:

// 引入路由以及vue,下面的是固定写法,照写就可以
import Vue from 'vue'
import Router from 'vue-router'
Vue.use(Router)
 
//创建路由实例
const router = new Router({
  linkActiveClass: 'app-active', // 路由点击选中时的颜色(app-active为自定义的class样式类)
  routes: [
    { // 根路径
	path: '/',
	redirect: '/home',
	component: () => import('@/pages/home')  // 路由懒加载写法
    },
    {
	path: '/home',
	name: 'home',
	component: () => import('@/pages/home'),
    }
})
 
/* 路由拦截器 路由跳转前的操作 */
router.beforeEach((to, from, next) => {
    // 获取缓存的 请求取消标识 数组,取消所有关联的请求
    let cancelArr = window.axiosCancel;
    cancelArr.forEach((ele, index) => {
        ele.cancel("取消了请求")  // 在失败函数中返回这里自定义的错误信息
        delete window.axiosCancel[index]
    })
    next()
})
/* 路由拦截器 路由跳转后的操作 */
router.afterEach(to => {
 
})
 
// 将路由导出,供外部接收,主要用于main.js接收
export default router