vue路由切换时取消之前的所有请求

在main.js文件里

import router from 'router/';
import Vue from 'vue';
Vue.Cancel = [];
router.beforeEach((to, from, next) => {
    while (Vue.Cancel.length > 0) {
        Vue.Cancel.shift()('cancel');
    }
    next();
})

ajax文件

import Vue from 'vue';
import axios from 'axios';
import VueAxios from 'vue-axios';

Vue.use(VueAxios, axios);

// 导入封装的回调函数
import {
    cbs,
    gbs
} from 'config/';

// 动态设置本地和线上接口域名
Vue.axios.defaults.baseURL = gbs.host;

/**
 * 封装axios的通用请求
 * @param  {string}   type      get或post
 * @param  {string}   url       请求的接口URL
 * @param  {object}   data      传的参数,没有则传空对象
 * @param  {object}   urlParams      url传参
 * @param  {Function} fn        回调函数
 * @param  {boolean}  tokenFlag 是否需要携带token参数,为true,不需要;false,需要。一般除了登录,都需要
 */
export default function ({
    type,
    path,
    data,
    params,
    urlParams,
    fn,
    errFn,
    tokenFlag,
    headers,
    opts
} = {}) {

    var options = {
        method: type,
        url: path,
        params: params,
        headers: headers && typeof headers === 'object' ? headers : {},
        cancelToken: new axios.CancelToken(function (cancel) {
            Vue.Cancel && Vue.Cancel.push(cancel)
        })        
    };

    //检测接口权限
    var api_flag = true;
    if (options.url && options.url.indexOf(gbs.host) && this.$store.state.user.userinfo.access_status === 1) {
        var url = options.url.replace(gbs.host, '');
        var api_routers = this.$store.state.user.userinfo.api_routers;
        if (!api_routers || !api_routers.constructor === Object || !api_routers[url]) {
            api_flag = false;
        }
    }

    var urlParamsArray = [];
    if (api_flag === true) {
        options[type === 'get' ? 'params' : 'data'] = data;

        // 用于url传参
        if (typeof (urlParams) == "object") {
            for (var k in urlParams) {
                urlParamsArray.push(k + '=' + urlParams[k])
            }
            options.url += '?' + urlParamsArray.join('&');
        }
        if (typeof (urlParams) == "string" || typeof (urlParams) == "number") {
            options.url += urlParams;
        }

        if(options.url.indexOf('?') > -1){
            options.url += '&_=' + (new Date()).getTime();
        }else{
            options.url += '?_=' + (new Date()).getTime();
        }

        // 分发显示加载样式任务
        this.$store.dispatch('show_loading');

        if (tokenFlag !== true) {
            //如果你们的后台不会接受headers里面的参数,打开这个注释,即实现token通过普通参数方式传
            // data.token = this.$store.state.user.userinfo.token;

            options.headers.token = this.$store.state.user.userinfo.token;
        }

        //扩展Promise使支持finally(),用了babel就不用手写了^.^
        // Promise.prototype.finally=function(callback){
        //     let Promise = this.constructor;
        //     return this.then(
        //         value  => Promise.resolve(callback()).then(() => value),
        //         reason => Promise.resolve(callback()).then(() => { throw reason })
        //     );
        // };
        //发送请求
        return new Promise((resolve, reject)=>{
            Vue.axios(options).then((res) => {
                this.$store.dispatch('hide_loading');
                if (res.data[gbs.api_status_key_field] === gbs.api_status_value_field || (res.status === gbs.api_status_value_field && !res.data[gbs.api_status_key_field])) {
                    fn(res.data);
                } else {
                    if (gbs.api_custom[res.data[gbs.api_status_key_field]]) {
                        gbs.api_custom[res.data[gbs.api_status_key_field]].call(this, res.data);
                    } else {
                        cbs.statusError.call(this, res.data);
                        if (errFn) {
                            errFn.call(this, res.data);
                        }
                    }
                }
                resolve(res.data);
            }).catch((err) => {
                if(err.response && err.response.status !== 403){
                    try{
                        errFn?errFn.call(this, this.$$lib__.isObject(err.response.data) ? err.response.data : {}):null;
                    }catch(err){
                        console.error(err.message);
                    }
                }
                if(err.response && err.response.data === ''){
                    cbs.statusError.call(this, {status: err.response.status});
                } else if (err.response && this.$$lib__.isObject(err.response.data)) {
                    cbs.statusError.call(this, err.response.data);
                }else if(err.response){
                    cbs.requestError.call(this, err);
                } else {
                    console.error('Error from ', '"'+path+'".', err.message);
                }
                reject(err);
            });
        });
    } else {
        this.$alert('您没有权限请求该接口!', '请求错误', {
            confirmButtonText: '确定',
            type: 'warning'
        });
    }
};

核心代码为cancelToken参数

var options = {
        method: type,
        url: path,
        params: params,
        headers: headers && typeof headers === 'object' ? headers : {},
        cancelToken: new axios.CancelToken(function (cancel) {
            Vue.Cancel && Vue.Cancel.push(cancel)
        })        
    };

你可能感兴趣的:(VUE,web)