最近一直在写Vue项目,和后台交互用的是官方推荐的axios。
Axios 是一个基于 promise 的 HTTP 库
官方教程里面有详细的使用方法,在此就不做详细描述了~
我们如果在每个需要使用的页面都引入axios 然后写 get、post方法,代码就会变得非常的冗余,会有很多重复的代码,并且需要修改某些通用属性的时候,可能就要涉及到所有的文件。
一个完整项目中,所有接口中通用的内容一般包括:
在文件目录src 下面新建一个api/api.js 文件夹和js文件,然后内部引用所需文件(此处错误信息通过自己封装的一个toast插件得以实现):
import axios from 'axios'
import router from '../router/index.js'
const serverUrl = 'http://172.16.134.81:3344' // 本地测试地址
接下来我们开始封装get请求
// 封装axios get
export function axiosGet(url, params) {
return axios({
url: `${serverUrl}${url}`,
method: 'get',
params
})
.then(res => {
if (res.data.code === 0) {
return Promise.resolve(res.data)
}
return Promise.reject(res)
})
.catch(err => {
return Promise.reject(err)
})
}
这里说明一下:
然后我们再封装post请求:
// 封装axios post
export function axiosPost(url, data) {
return axios({
url: `${serverUrl}${url}`,
method: 'POST',
data: data,
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
}
})
.then(res => {
if (res.data.code === 0) {
return Promise.resolve(res.data)
}
return Promise.reject(res.data)
})
.catch(err => {
return Promise.reject(err)
})
}
然后封装一个用axios上传文件的请求:
// 文件上传
function axiosUpload(url, data, callback) {
const params = data
return axios
.post(`${serverUrl}${url}`, params, {
// 上传进度处理事件
onUploadProgress(progressEvent) {
if (progressEvent.lengthComputable) {
callback(progressEvent)
}
}
})
.then((res) => {
if (res.data.code === 0) {
return Promise.resolve(res.data)
}
return Promise.reject(res.data)
})
.catch(err => {
return Promise.reject(err)
})
}
我们注册一个全局的mixin混入,内容是我们统一处理的一些错误提示,在main.js中:
const networkErr = ['404', '405', '500', '504', '205', '400', 'Network Error']
Vue.mixin({
methods: {
errorFun(err) {
const status = networkErr.some((item) => {
const errs = err.toString()
return errs.includes(item)
})
if (status) {
this.$toast('网络错误,请检查网络设置')
return false
}
const response = err.response
// 登陆过期处理
if (response && response.data && response.data.code === 100009) {
this.$toast('登录已过期,请重新登录')
sessionStorage.clear()
this.$router.push('/login')
return false
}
this.$toast(err.data.msg)
}
}
})
这里面我只列举了一个特殊的处理方法(登陆过期):
和后台约定 当接口返回的状态码为 100009时,则登录超时,此时需要在页面弹出一个message提示,并且清空sessionStorage(如果项目中没有使用则忽略)并且将页面跳转到登录页面
如果还有其他公用的错误提示(例如 500 等)都可以在统一的错误函数中写好,这样就不用再每个页面都重复的写上这些错误处理。然后将这些公用错误之外的其他错误信息返回页面的catch()方法中单独处理~
此时,主要三种请求方法已经封装完成,那么我们怎么使用这三个封装的方法去请求接口呢?
在 api.js 后面继续写入具体的接口调用:
// 登录
export function postLogin(data = {}) {
const url = '/access/login'
return axiosPost(url, data)
}
// 登出
export function getLogout(data = {}) {
const url = '/access/logout'
return axiosGet(url, data)
}
// 资质认证--文件上传
export function postUploadFile(data = {}, callback) {
const url = '/upload/add'
return axiosUpload(url, data, callback)
}
这个时候,我们的api.js也算是大功告成了。在Vue文件中我们应该如何调用:
import { postLogin, getLogout, postUploadFile } from '@/api/api.js';
export default {
methods: {
/**
* 登录
*/
login() {
const data = {
name: 'xxxxx',
password: 'xxxxxxx'
};
postLogin(data)
.then(res => {
Message({
message: '登录成功',
type: 'success'
});
})
.catch(err => {
this.errorFun(err)
});
},
/**
* 登出
*/
logout() {
getLogout()
.then(res => {
// 退出操作
})
.catch(err => {
this.errorFun(err)
});
},
/**
* 上传文件
*/
fileChange(e) {
const params = new FormData();
const file = e.target.files[0];
const reader = new FileReader();
reader.readAsDataURL(file);
params.set('file', file);
if (file.size <= 1000000) {
postUploadFile(params, pro => {
// pro 为上传进度相关的数据,再此将进度映射到页面中
})
.then(res => {
reader.onload = (() => {
this.imgUrl = reader.result; // 图片预览 base64码
})();
})
.catch(err => {
this.errorFun(err)
});
}
}
}
};
至此,一个完整的axios请求封装与调用已经完成~
本文章的很多写法和理念还不够完善,本人也只是个前端海洋中的一条淡水鱼,在此希望得到广大同行们的指教,共同进步!