看到标题你一定很诧异吧,没错,axios是很NB,很棒,连vue官方文档都推荐他。但是再好的工具到每个人、每个项目都需要细心再打磨一番,毕竟工欲善其事必先利其器。这篇文章只是使用推荐,如有遗漏错误,请不吝指教,谢谢。
axios安装
$ npm install axios
$ #OR
$ cnpm i axios # 淘宝镜像源,速度更快
封装
// 随便新建一个js文件,比如: demo1.js
import axios from 'axios';
import store from '@/store';
export const GET = 'get';
export const POST = 'post';
const REQUEST_TIME = 8000; // 超时时间
export default class Request {
/** 这里我传递的是对象,你也可以修改为直接传值:method,url,data...... */
constructor(options = {}) {
this.options = options;
this.url = options.url;
this.data = options.data;
/** 判断请求方法,只要含‘p’即认定为POST请求,否则走默认get请求,
* 这里你可以再封装一个判断使用何种方法的函数,如果像我只有post和get就不用这么麻烦了。
*/
this.method =
options.method.toLocaleLowerCase().indexOf('p') > -1 ? POST : GET;
this.instance = this._createInstance(); // 创建实例
// 必须调用this.instance这个实例配置
this._defaultConfiguration(); // 默认设置
this._requestInterceptor(); // 请求拦截器
this._responseInterceptor(); // 应答拦截器
}
/**
* set default configuration
* @memberof Request
*/
_defaultConfiguration() {
this.instance.defaults.headers = {
'X-Requested-With': 'XMLHttpRequest'
};
this.instance.defaults.timeout = REQUEST_TIMEOUT;
}
/**
* request interceptors
* @memberof Request
*/
_requestInterceptor() {
this.instance.interceptors.request.use(
config => {
// do something before request is sent
/**
* add userId deal with base64
* [PanJiaChen](https://juejin.im/post/59097cd7a22b9d0065fb61d2)
*/
if (store.state.user.id) {
config.headers['id'] = store.state.user.id; // 让每个请求携带token--['userId']为自定义key 根据实际情况自行修改
}
return config;
},
error => {
return Promise.reject(error);
}
);
}
/**
* response interceptor
* @memberof Request
*/
_responseInterceptor() {
this.instance.interceptors.response.use(
response => {
return response;
},
error => {
/** request timeout */
this._timeoutHandler(error);
return Promise.reject(error);
}
);
}
/**
* timeout handler and redirect to maintenance page
* @param {object} error response error data
*/
_timeoutHandler(error) {
if (
error.code === 'ECONNABORTED' &&
error.message.indexOf('timeout') > -1
) {
console.error('_timeoutHandler()', 'request timeout', error);
router.push({ name: 'Maintenance' }); // 跳转维护页,也可以是404页
}
}
/**
* create axios instance
* @returns axios instance
* @memberof Request
*/
_createInstance() {
let config = {
headers: { 'Content-Type': 'application/json;charset=UTF-8' },
url: this.url,
method: this.method
};
if (this.options.hasOwnProperty('headers') && this.options.headers) {
config.headers = this.options.headers;
}
if (this.method === GET) {
config.params = this.data;
} else {
config.data = this.data;
}
/**
* Remember: if you want to set global configuration of axios before create instance
* just like this: axios.defaults.timeout = REQUEST_TIMEOUT;
*/
return axios.create(config);
}
/** get all response paramter */
async getData() {
try {
let response = await this.instance();
if (response.data.rel) {
// 我们代表返回正确,这里的rel为true
return response.data;
}
throw response.data;
} catch (err) {
console.error(`${this.method} ${this.url}`, 'fail', err);
return err;
}
}
}
API
// 新建一个api.js,用来存储接口和方法,我这里只是为了展示,你可以新建一个文件夹,然后不同模块新建不同的js文件
/** npm package: https://www.npmjs.com/package/qs */
import qs from 'qs';
import Request, { GET, POST } from '@/common/js/request';
export async function getUserInfo(data) {
let request = new Request({
url: '/test/user/info',
method: GET,
data
});
return request.getData();
}
export async function postPay(data) {
let request = new Request({
url: '/test/pay/payment',
method: POST,
data
});
return request.getData();
}
/**
* 使用axios发送POST请求,请求参数为 formdata 格式
* 切记:formdata格式一定要使用 qs.stringify 进行转换
*/
export async function postLogin(data) {
let request = new Request({
url: '/test/login',
method: POST,
headers: {
'Content-Type': 'application/x-www-form-urlencoded;charset=UTF-8'
},
data: qs.stringify(data)
});
return request.getData();
使用
// A页面
import { getUserInfo } from '@/common/api';
methods: {
async _getUserInfo() {
let data = await getUserInfo({
id: test1
});
// 处理返回的data参数
}
}
参考链接
[1] axios官方文档(英文) axios仓库
[2] 看云 axios文档(中文)
[3] 愣锤 vue中Axios的封装和API接口的管理
[4] 花裤衩 request.js
[5] 花裤衩 api/role.js
[6] 花裤衩 role.vue