fetch使用,包含上传图片到七牛和上传excel到后台,基于v
2020-06-19 本文已影响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