微信小程序 接口请求封装
一、axios utils/request/axios.js
/**
* Copyright © 2020-present LiuDanYang. All rights Reserved.
*/
const axios = (function () {
class Axios {
constructor() {
this.defaults = {
baseUrl: "",
};
this.interceptors = {
request: new InterceptorManager(),
response: new InterceptorManager(),
};
}
wxRequest(c) {
return new Promise((resolve, reject) => {
c = this.interceptors.request.func(c);
c.url = c.url.startsWith("http") ? c.url : c.baseUrl + c.url;
c.success = (res) => {
resolve(this.interceptors.response.func(res));
};
c.fail = (res) => {
reject(this.interceptors.response.func(res));
};
wx.request(c);
});
}
}
Array.prototype.forEach.call(
["options", "get", "head", "post", "put", "delete", "trace", "connect"],
function (m) {
Axios.prototype[m] = function (url, data, config) {
return this.wxRequest(
merge(
this.defaults,
{
url: url,
method: m,
data: data,
},
config || {}
)
);
};
}
);
class InterceptorManager {
constructor() {
this.func = function (data) {
return data;
};
}
use(fn) {
this.func = fn;
}
}
function merge(axiosDefaultConfig, data, config) {
let cloneAxios = deepClone(axiosDefaultConfig);
let cloneData = deepClone(data);
let cloneConfig = deepClone(config);
return Object.assign(cloneAxios, cloneData, cloneConfig);
}
// 深拷贝
function deepClone(obj) {
let _obj = JSON.stringify(obj),
objClone = JSON.parse(_obj);
return objClone;
}
return new Axios();
})();
export default axios;
二、封装文件 utils/request/index.js
/**
* Copyright © 2020-present LiuDanYang. All rights Reserved.
*/
import axios from "./axios";
// import { getToken } from "@u/auth";
/**
* axios defaults 配置
*/
axios.defaults = {
baseUrl: "http://rap2.taobao.org:38080/",
timeout: 60000,
};
/**
* 全局 请求拦截器, 支持添加多个拦截器
* 例如: 配置token、添加一些默认的参数
* `return config` 继续发送请求
*/
axios.interceptors.request.use(
(config) => {
// 设置Token
if (config.method === "post") {
config.data = {
...config.data,
//access_token: getToken(),
_t: Date.parse(new Date()) / 1000
};
} else if (config.method === "get") {
config.params = {
...config.params,
//access_token: getToken(),
_t: Date.parse(new Date()) / 1000
};
}
return config;
},
(error) => {
// 做一些请求错误
console.error(error);
return Promise.reject(error);
}
);
/**
* 全局 响应拦截器, 支持添加多个拦截器
* 例如: 根据状态码选择性拦截、过滤转换数据
* @param {Object} res 请求返回的数据
* @return {Promise<reject>}
*/
axios.interceptors.response.use(
async (res) => {
const { data, statusCode: status } = res;
try {
return await handleCode({ data, status });
} catch (err) {
return Promise.reject(err);
}
},
(err) => {
// 做一些请求错误
console.error(err);
return Promise.reject(err);
}
);
/**
* 处理 HTTP 状态码
* @param data {Object} 请求返回的数据
* @param status {String} HTTP状态码
* @returns {Promise<never>|*}
*/
function handleCode({ data, status }) {
const STATUS = {
"200"() {
return data;
},
"400"() {
return Promise.reject(new Error("请求错误"));
},
"401"() {
return Promise.reject(new Error("请求未授权"));
},
"403"() {
return Promise.reject(new Error("拒绝请求"));
},
"500"() {
return Promise.reject(new Error("服务器错误"));
},
};
// 有状态码但不在这个封装的配置里,就直接返回错误
return STATUS[status]
? STATUS[status]()
: Promise.reject(new Error(data.data || "请求错误"));
}
export default axios;
三、管理接口文件 utils/request/xhr.js
/**
* Copyright © 2020-present LiuDanYang. All rights Reserved.
*/
import axios from "./index";
/**
* get 请求方式
* @param url {String} 接口地址
* @param params {Object} 接口参数
* @returns {AxiosPromise}
* @constructor
*/
export function mGet(url, params) {
return new Promise((resolve, reject) => {
axios
.get(url, params)
.then((res) => {
resolve(res);
})
.catch((err) => {
reject(err);
});
});
}
/**
* post 请求方式
* @param url {String} 接口地址
* @param data {Object} 接口参数
* @returns {AxiosPromise}
* @constructor
*/
export function mPost(url, data) {
return new Promise((resolve, reject) => {
axios
.post(url, data)
.then((res) => {
resolve(res);
})
.catch((err) => {
reject(err);
});
});
}
/**
* put 请求方式-用于修改全部数据
* @param url {String} 接口地址
* @param data {Object} 接口参数
* @returns {AxiosPromise}
* @constructor
*/
export function mPut(url, data) {
return new Promise((resolve, reject) => {
axios
.put(url, data)
.then((res) => {
resolve(res);
})
.catch((err) => {
reject(err);
});
});
}
/**
* patch 请求方式-用于修改单项或多项数据
* @param url {String} 接口地址
* @param data {Object} 接口参数
* @returns {AxiosPromise}
* @constructor
*/
export function mPatch(url, data) {
return new Promise((resolve, reject) => {
axios
.patch(url, data)
.then((res) => {
resolve(res);
})
.catch((err) => {
reject(err);
});
});
}
/**
* delete 请求方式
* @param url {String} 接口地址
* @param params {Object} 接口参数
* @returns {AxiosPromise}
*/
export function mDelete(url, params) {
return new Promise((resolve, reject) => {
axios
.delete(url, params)
.then((res) => {
resolve(res);
})
.catch((err) => {
reject(err);
});
});
}
四、接口文件 api/home.js
/**
* Copyright © 2020-present LiuDanYang. All rights Reserved.
*/
import { mPost } from "../utils/request/xhr";
const getArticleList = (params) => mPost("app/mock/262524/get/article/list", params);
export { getArticleList };
五、js 使用接口 index/index.js
/**
* 数据源来自于rap2 mock数据,调用url: http://rap2.taobao.org:38080/app/mock/262524/get/article/list
*/
import { getArticleList } from "../api/home";
Page({
data: {
list: [], // 列表数据
pages: 1, // 当前页数
pageSize: 20, // 每页数据的个数
isLoading: false, // 正在加载中...,默认 false,隐藏
isLoadingMore: false, //没有更多内容了,默认 false,隐藏
},
/**
* 生命周期函数--监听页面加载
*/
onLoad() {
this.loadData();
},
/**
* 请求数据封装
*/
loadData() {
let t = this;
let pages = t.data.pages,
pageSize = t.data.pageSize;
getArticleList({
pages: pages,
pageSize: pageSize,
})
.then((res) => {
let resData = res.data; // 返回的数据
let resNum = resData.length; // 返回的数据列表个数
// 如果返回的数据列表个数小于每页数据的个数
if (resNum < t.data.pageSize) {
t.setData({
isLoadingMore: true,
isLoading: false,
list: resData,
});
} else {
t.setData({
isLoadingMore: false,
isLoading: true,
list: resData,
});
}
})
.catch((err) => {
console.log("封装请求错误返回", err);
});
},
});
具体根据自己的需求去修改
微信开发者工具:接口封装demo代码片段