先放一个正确的封装之后的成果:
/**
* 微信小程序标准版:统一封装的 http 请求类
*/
class Http {
/**
* prefix of Http _get _post ...
* @param baseUrl: string
*/
constructor(baseUrl = '') {
if (typeof baseUrl !== 'string') {
throw new Error('Http baseUrl must be a string');
}
if (baseUrl.TrimStr() == '') {
throw new Error('Http baseUrl can not be empty');
}
this.baseUrl = baseUrl;
}
/**
* api address
* @param url: string
*/
checkUrl(url) {
if (url.indexOf('://') == -1) {
url = this.baseUrl + url
}
return url
}
/**
* 统一的请求方法
* @param{ url:'api 地址',data:'数据',header:'自定义请求头内容',loading:'是否显示请求 loading', ...others:'其他参数'}
*/
http({
url = '',
data = {},
header = {},
loading = false,
...others
} = {}) {
return new Promise((resolve, reject) => {
if (loading) {
wx.showLoading({
title: '加载中 ...',
mask: true
})
}
wx.request({
url: this.checkUrl(url),
data,
header,
...others,
success: (res) => {
if (res.data.code_status === 0) {
resolve(res.data);
} else {
reject(res.data.msg)
}
},
fail: (err) => {
wx.showToast({
title: '网络错误,请稍后再试',
icon: 'none'
})
},
complete: () => {
wx.hideLoading()
}
})
})
}
/* 这里修改成箭头函数,里边的 this 指向不跟着调用者改变,指向的就是本身外层的 this 对象 */
_get = (url, data, loading = false, header = {
'Content-Type': 'application/json'
}) => {
return this.http({
url,
data,
header,
loading
})
}
/* 这里修改成箭头函数,里边的 this 指向不跟着调用者改变,指向的就是本身外层的 this 对象 */
_post = (url, data, loading = false, header = {
'Content-Type': 'application/json'
}) => {
console.log(this)
return this.http({
url,
data,
header,
method: 'post',
loading
})
}
}
String.prototype.TrimStr = function () {
return this.replace(/(^\s*)|(\s*$)/g, '');
}
export {
Http
}
接下来看一下封装过程:
首先先封装一个 class 放入一个独立的文件内:utils/http.js
/**
* 微信小程序标准版:统一封装的 http 请求类
*/
class Http {
/**
* prefix of Http _get _post ...
* @param baseUrl: string
*/
constructor(baseUrl = '') {
if (typeof baseUrl !== 'string') {
throw new Error('Http baseUrl must be a string');
}
if (baseUrl.TrimStr() == '') {
throw new Error('Http baseUrl can not be empty');
}
this.baseUrl = baseUrl;
}
/**
* api address
* @param url: string
*/
checkUrl(url) {
if (url.indexOf('://') == -1) {
url = this.baseUrl + url
}
return url
}
/**
* 统一的请求方法
* @param{ url:'api 地址',data:'数据',header:'自定义请求头内容',loading:'是否显示请求 loading', ...others:'其他参数'}
*/
http({
url = '',
data = {},
header = {},
loading = false,
...others
} = {}) {
return new Promise((resolve, reject) => {
if (loading) {
wx.showLoading({
title: '加载中 ...',
mask: true
})
}
wx.request({
url: this.checkUrl(url),
data,
header,
...others,
success: (res) => {
if (res.data.code_status === 0) {
resolve(res.data);
} else {
reject(res.data.msg)
}
},
fail: (err) => {
wx.showToast({
title: '网络错误,请稍后再试',
icon: 'none'
})
},
complete: () => {
wx.hideLoading()
}
})
})
}
_get(url, data, loading = false, header = {
'Content-Type': 'application/json'
}) {
return this.http({
url,
data,
header,
loading
})
}
_post(url, data, loading = false, header = {
'Content-Type': 'application/json'
}){
console.log(this)
return this.http({
url,
data,
header,
method: 'post',
loading
})
}
}
String.prototype.TrimStr = function () {
return this.replace(/(^\s*)|(\s*$)/g, '');
}
export {Http}
在 app.js 内部引入并在 index.js 使用的时候发现了另外的问题:
import {Http} from './utils/http'
const baseUrl = 'https://mini.brecovered.cn/';
const $Http = new Http(baseUrl);
App({
onLaunch: function () {
},
$Http:$Http, // 将 Http 本身也给 app 添加一个全局变量,但是使用它的话调用总是需要加上 $Http. 前缀,不喜欢,所以把下面两个也放进去
_post:$Http._post, // _post 也注册上去
_get:$Http._get // _get 也注册上去
})
在 index.js 使用:
//index.js
//获取应用实例
const app = getApp()
Page({
data: {
},
onLoad: function () {
app._post('aaa')
.then(res=>{
console.log(res)
})
.catch(err=>{
console.log(err)
})
}
})
报了一个错:
可以看到,这个 this 是 app.js 里边的 App 对象,不是 Http 类,修改使用的请求,用 $Http._post
app.$Http._post('aaa')
.then(res=>{
console.log(res)
})
.catch(err=>{
console.log(err)
})
这时候看到请求是对的,http.js 内部的 _post 输出的 this 也是 Http 类本身,没问题。
这时候不得不提一嘴 javascript 的 function 内部 this 指向问题了,像这种的调用,内部 this 指向都是调用者,也就是 .(点)funcName
前边的对象,这里可以修改一下封装的 class ,index.js 里边的调用方式不变,还是直接 app._post(连带 app._get 一起修改):
/**
* 微信小程序标准版:统一封装的 http 请求类
*/
class Http {
/**
* prefix of Http _get _post ...
* @param baseUrl: string
*/
constructor(baseUrl = '') {
if (typeof baseUrl !== 'string') {
throw new Error('Http baseUrl must be a string');
}
if (baseUrl.TrimStr() == '') {
throw new Error('Http baseUrl can not be empty');
}
this.baseUrl = baseUrl;
}
/**
* api address
* @param url: string
*/
checkUrl(url) {
if (url.indexOf('://') == -1) {
url = this.baseUrl + url
}
return url
}
/**
* 统一的请求方法
* @param{ url:'api 地址',data:'数据',header:'自定义请求头内容',loading:'是否显示请求 loading', ...others:'其他参数'}
*/
http({
url = '',
data = {},
header = {},
loading = false,
...others
} = {}) {
return new Promise((resolve, reject) => {
if (loading) {
wx.showLoading({
title: '加载中 ...',
mask: true
})
}
wx.request({
url: this.checkUrl(url),
data,
header,
...others,
success: (res) => {
if (res.data.code_status === 0) {
resolve(res.data);
} else {
reject(res.data.msg)
}
},
fail: (err) => {
wx.showToast({
title: '网络错误,请稍后再试',
icon: 'none'
})
},
complete: () => {
wx.hideLoading()
}
})
})
}
/* 这里修改成箭头函数,里边的 this 指向不跟着调用者改变,指向的就是本身外层的 this 对象 */
_get = (url, data, loading = false, header = {
'Content-Type': 'application/json'
}) => {
return this.http({
url,
data,
header,
loading
})
}
/* 这里修改成箭头函数,里边的 this 指向不跟着调用者改变,指向的就是本身外层的 this 对象 */
_post = (url, data, loading = false, header = {
'Content-Type': 'application/json'
}) => {
console.log(this)
return this.http({
url,
data,
header,
method: 'post',
loading
})
}
}
String.prototype.TrimStr = function () {
return this.replace(/(^\s*)|(\s*$)/g, '');
}
export {
Http
}
再次调用请求查看:
可以看到,输出的 this 就是当前的 class 对象,这样就没问题了