美文网首页
fetch使用,包含上传图片到七牛和上传excel到后台,基于v

fetch使用,包含上传图片到七牛和上传excel到后台,基于v

作者: 索哥来了 | 来源:发表于2020-06-19 11:21 被阅读0次

    使用前,初略了解fetch:https://developer.mozilla.org/zh-CN/docs/Web/API/Fetch_API
    考虑到fetch的兼容性还不是很好,在不支持fetch的时候调用了 之前封装的axios,可参考之前的文章https://www.jianshu.com/p/f3268f923465
    然后直接上代码:

    import commonFun from './commonFun'
    import { Message } from 'element-ui';
    import store from '../store'
    import ajax from './ajax'
    
    let baseURL = process.env.VUE_APP_HOST;
    let isQiNiu = false;//isQiNiu可以用全局参数是因为,不会同时存在多个接口进行  又是七牛,又不是七牛的
    const ajaxParams = {};//存放noLoading,避免被覆盖
    
    const myfetch = (url, params = {}, type = 'get', myConfig = {}) => {
        type = type.toLowerCase();
        if(!window.fetch){
            return ajax[type](url, params, myConfig);
        }
    
        isQiNiu = ( url == '//up-z2.qiniup.com/'|| 
                    url == 'http://up-z2.qiniup.com/' || 
                    url == 'https://up-z2.qiniup.com/');
    
        let config = {
                headers: {
                    'token': localStorage.loginToken,
                }
            },
            sendUrl = commonFun.urlHasHttp(url) ? url : baseURL + url;
    
        // 上传文件 不设置Content-Type, 不是上传文件就设置
        if( !(myConfig.type == 'formData' || isQiNiu) ){
            config.headers['Content-Type'] = 'application/json';//提交的数据类型
        }
    
        if(type == 'get'){
            if(params){
                for(var i in params){
                    sendUrl += (sendUrl.includes('?')?'&':'?') + i + '=' + params[i]
                }
            }
        }else{
            config.body = (myConfig.type == 'formData' || isQiNiu) ? params : JSON.stringify(params);
        }
    
        ajaxParams[sendUrl] = 0; //没有loading
        if(!myConfig.noLoading){
            ajaxParams[sendUrl] = 1; //有loading
            store.commit('addLoading');
        }
        store.commit('addAjax');
    
    
        return new Promise( (resolve, reject) => {
            fetch(sendUrl, {
                ...config,
                method: type,
                mode: 'cors', //跨域
            })
            .then(res => {
                if(res.ok){
                    return res.json()
                }
            })
            .then(data => {
                if(ajaxParams[sendUrl] === 1){
                    store.commit('subLoading');
                }
                store.commit('subAjax');
    
                if(data.code === 0 || data.code === '0'){
                    cb();
                    resolve(data.data);
                }else if(data.code == 10001){
                    store.commit('setAjaxMsg', '登录过期');
                    cb();
                }else{
                    if(isQiNiu){
                        if(data.key){
                            cb();
                            resolve(data);
                        }else{
                            store.commit('setAjaxMsg', '上传七牛失败');
                            cb();
                        }
                    }else{
                        if(store.state.ajaxMsg != '登录过期'){
                            store.commit('setAjaxMsg', data.message);
                        }
                        cb();
                    }
                }
            })
            .catch(err => {
                // 和axios不一样,fetch请求不管成功失败都会进入上面的函数,进入这里一般是因为data里面没有code,上面判断code而导致“写法错误”进入这里
                console.log(err, JSON.stringify(err));
                if(store.state.ajaxMsg != '登录过期'){
                    store.commit('setAjaxMsg', '网络异常,请稍后再试');
                }
                cb();
            })
        })
    }
    
    function cb(){
        if(store.state.ajaxNum <= 0 && store.state.ajaxMsg){
            let msg = store.state.ajaxMsg;
            store.commit('setAjaxMsg', '');
            if(msg != '登录过期'){
                Message(msg);
            }else{
                Message({
                    message: msg,
                    duration: 1000,
                    onClose: function(){
                        localStorage.loginToken = '';
                        window.location.href = process.env.VUE_APP_LOGINHOST;
                    }
                })
            }
        }
    }
    
    export default myfetch;
    

    vuex里面存放的状态:
    之所以分成loadingNum和ajaxNum,是因为有的请求可能不加loading

    import Vue from "vue";
    import Vuex from "vuex";
    
    Vue.use(Vuex);
    
    export default new Vuex.Store({
        state: {
            loadingNum: 0,
    
            ajaxMsg: '',//多个请求的时候 只弹一个
            ajaxNum: 0,
        },
        mutations: {
            addLoading: (state) => state.loadingNum += 1,
            subLoading: (state) => state.loadingNum = state.loadingNum > 0?state.loadingNum-1:0,
    
            setAjaxMsg: (state, msg) => state.ajaxMsg = msg,
            addAjax: (state) => state.ajaxNum += 1,
            subAjax: (state) => state.ajaxNum = state.ajaxNum > 0?state.ajaxNum-1:0,
        },
        actions: {},
    });
    

    然后直接使用:

    import myfetch from '@/function/fetch'
    
    // get,默认方式get
    myfetch('/aaaa', {a: 2,b: 3})
        .then(res => {
            console.log(res)
        })
        .catch(err => {
            console.log(err);
        })
    //post、put、delete
    //noLoading 表示没有loading转圈圈,不加这个参数表示是有的
    myfetch('/aaaa', {a: 2,b: 3}, 'post', {noLoading: true})
        .then(res => {
            console.log(res)
        })
        .catch(err => {
            console.log(err);
        })
    
    // 上传excel
    <input type="file" accept="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" @change="uploadExcel">
    <el-button size="small" type="primary" @click="confirmUpload">确认上传</el-button>
    
    uploadExcel(e){
        let me = this;
        let file = e.target.files[0];
    
        if(file){
            // console.log(file.name);
            if(!file.name.endsWith('.xlsx')){
                me.$message('仅支持.xlsx文件!');
                e.target.value = '';
                return false;
            }
    
            let params = new FormData();
            params.append('file', file);
            this.uploadData = params;
        }
    },
    confirmUpload(){
        let me = this;
    
        let params = this.uploadData;
        if(!params){
            me.$message('请先上传Excel!')
            return false;
        }
    
        params.append('aa', 1);// 可以增加其他字段
        let url = '/bbb';
    
        myfetch(url, params, 'post', {type: 'formData'})
        .then(res => {
            console.log(res)
        })
    },
    
    

    上传图片和上传文件类似,封装方法可查看这篇文章https://www.jianshu.com/p/86fc1ab2112d

    相关文章

      网友评论

          本文标题:fetch使用,包含上传图片到七牛和上传excel到后台,基于v

          本文链接:https://www.haomeiwen.com/subject/xbkvxktx.html