1. 程式人生 > >vue+typescript封裝axios,實現取消重複請求

vue+typescript封裝axios,實現取消重複請求

vue-cli3可以直接生成vue+typescript專案,然後對axios進行封裝,實現攔截多次重複請求,並取消。 直接擼程式碼(也是借鑑網上的,做了修改)

  1. 在根目錄下新建axios.tool.ts檔案
import Vue from 'vue';
import router from './router';
import axios from 'axios';
import qs from 'qs';
import { Base } from './base'; // 匯入全域性環境變數
const base = new Base();
// 取消請求
const CancelToken = axios.CancelToken;
// 是否需要攔截code==-1的狀態
let is_log: boolean = false;
// 設定預設請求頭
axios.defaults.headers = {
    'X-Requested-With': 'XMLHttpRequest',
    'Content-Type': 'application/x-www-form-urlencoded',
};
axios.defaults.baseURL = base.url();
// 請求超時的時間限制
axios.defaults.timeout = 20000;
// 開始設定請求 發起的攔截處理
// config 代表發起請求的引數的實體
let requestName: any;
axios.interceptors.request.use((config: any) => {
    // 得到引數中的 requestName 欄位,用於決定下次發起請求,取消對應的 相同欄位的請求
    // 如果沒有 requestName 就預設新增一個 不同的時間戳
    if (config.method === 'post') {
        if (config.data && qs.parse(config.data).requestName) {
            requestName = qs.parse(config.data).requestName;
        } else {
            requestName = new Date().getTime();
        }
        if (config.data.indexOf('is_log') !== -1) {
            is_log = true;
        }
    } else {
        if (config.params && config.params.requestName) {
            requestName = config.params.requestName;
        } else {
            requestName = new Date().getTime();
        }
        if (config.params.is_log) {
            is_log = true;
        }
    }
    // 判斷,如果這裡拿到的引數中的 requestName 在上一次請求中已經存在,就取消上一次的請求
    if (requestName) {
        if (axios[requestName] && axios[requestName].cancel) {
            axios[requestName].cancel('取消了請求');
        }
        config.cancelToken = new CancelToken( (c: any) => {
            axios[requestName] = {};
            axios[requestName].cancel = c;
        });
    }
    return config;
}, (error: any) => {
    return Promise.reject(error);
});

// 請求到結果的攔截處理
axios.interceptors.response.use( (config: any) => {
    // 返回請求正確的結果
    if ((!is_log) && config.data.code === -1) {
        router.push({path: '/login'});  // 進入登陸頁面
    }
    if (config.data.code === -2) {
        router.push({path: '/'}); // 進入實名認證
    }
    return config.data;
}, (error: any) => {
    return Promise.reject(error);
    // 錯誤的請求結果處理,這裡的程式碼根據後臺的狀態碼來決定錯誤的輸出資訊
});
// 將axios 的 post 方法,繫結到 vue 例項上面的 $post
Vue.prototype.$post =  (url: any, params: any) => {
    return new Promise((resolve, reject) => {
        axios.post(url, qs.stringify(params)).then((res: any) => {
            resolve(res);
        }).catch((err: any) => {
            reject(err);
         });
     });
};
// 將axios 的 get 方法,繫結到 vue 例項上面的 $get
Vue.prototype.$get =  (url: any, params: any) => {
    return new Promise((resolve, reject) => {
        axios.get(url, { params: params }).then((res: any) => {
            resolve(res); // 返回請求成功的資料 data
        }).catch((err: any) => {
            reject(err);
        });
    });
};
  1. 在shims-vue.d.ts中宣告qs模組,因為axios中沒有qs的ts檔案暴露
declare module 'qs' {
  const qs: any;
  export default qs;
}
  1. 在main.ts中引入
import './axios.tool'; // 匯入封裝好的axios
  1. 在vue元件中使用
 this.$get("/userMessageAssociation/isRead", { is_log: true , requestName: 'get'}).then( (res: any) => {
    console.log(res);
 });