背景
微信小程序作为一种轻量级的应用开发框架,已经成为许多开发者的首选。在小程序开发中,网络请求是常见的需求之一。为了提高代码的复用性和开发效率,我们可以封装网络请求,使其更加易用和灵活。本文将介绍如何在微信小程序中封装请求,让开发变得更加便捷。
封装请求的优势
1、代码复用性
通过封装请求,我们可以将网络请求相关的代码抽离出来,形成一个独立的请求模块。这样,在多个页面中都可以复用这个模块,避免了代码的重复编写,提高了代码的复用性。
2、逻辑解耦
将网络请求封装成一个独立的模块,可以使代码逻辑更加清晰和简洁。不同的业务逻辑可以独立处理,降低了模块间的耦合度,提高了代码的可维护性和可测试性。
3、错误处理和异常捕获
封装请求的过程中,我们可以加入错误处理和异常捕获的逻辑。这样,在请求发生错误或异常时,我们可以统一处理,并给予用户友好的提示信息,提升了用户体验。
环境的配置
根目录建一个config文件夹后新建env.config.js文件,根据自己项目配置需要的配置参数,代码如下:
const envConf = {
// 开发环境
develop: {
MODE: 'dev',
SERVER_URL: '接口网关地址',
APP_ID: '项目appid'
},
// 测试环境
trial: {
MODE: 'test',
SERVER_URL: '接口网关地址',
APP_ID: '项目appid'
},
// 线上环境
release: {
mode: 'prod',
SERVER_URL: '接口网关地址',
APP_ID: '项目appid'
}
}
module.exports = {
env: envConf[__wxConfig.envVersion]
}
请求封装
- config文件下创建一个request.js文件,根据实际业务场景进行兼容修改;
- 封装设置了loadingCount这个参数,为了解决同个页面多个接口请求并发loading出现闪屏等问题;
- 请求头增加了POST_PARAMS判断,因为公司场景post请求存在参数放到query中而不是body,做了这个处理;
- 封装代码如下:
import { env } from '../config/env.config'
// 不用token校验的地址
const exceptionAddrArr = []
// 多并发请求记录控制loading
let loadingCount = 0
// 无需loading白名单
const loadingWhiteList = []
// 请求头处理函数
const createHeader = (url, type) => {
let header = {}
if (type == 'POST_PARAMS') {
header = {
'content-type': 'application/x-www-form-urlencoded',
}
} else {
header = {
'content-type': 'application/json',
}
}
//排除请求的地址不需要token的地址
if (exceptionAddrArr.indexOf(url) === -1) {
header['token'] = wx.getStorageSync('userinfo').token || ''
}
return header
}
// 请求封装
const request = (option) => {
const { url, method, params, headersType, loadingTxt = 'loading...', loading = true } = option
let header = createHeader(url, headersType || method)
// loading
if (!loadingWhiteList.includes(url) && loading) {
loadingCount++
if (loadingCount > 0) {
wx.showLoading({ title: loadingTxt, mask: true })
}
}
return new Promise((resolve, reject) => {
wx.request({
url: env.SERVER_URL + url,
method: method,
data: params,
header: header,
success(res) {
if (res.data && res.data.code === 200) {
resolve(res.data)
} else if (res.data.code === 403) {
// 403是没登录,不做处理
} else {
wx.showModal({
title: '提示',
content: res.data.msg || '请求失败',
showCancel: false
})
reject(res.data)
}
},
fail(error) {
wx.showModal({
title: '提示',
content: error || '请求失败',
showCancel: false
})
reject(error.data)
},
complete(v) {
if (!loadingWhiteList.includes(url) && loading) {
loadingCount--
setTimeout(() => {
if (loadingCount <= 0) {
loadingCount = 0
wx.hideLoading()
}
}, 0)
}
}
})
})
}
export default {
get: (option) => {
return request({ method: 'get', ...option })
},
post: (option) => {
return request({ method: 'post', ...option })
},
delete: (option) => {
return request({ method: 'delete', ...option })
},
put: (option) => {
return request({ method: 'put', ...option })
}
}
接口管理
根目录新建一个api文件夹,统一管理接口,如下在api下新建了一个user.js来管理接口
// 引入封装的request
import request from '../../config/request'
export const getUserInfo = (params) => {
return request.get({ url: '/frontend/user/getUserInfo', params })
}
export const unbindMobile = (params) => {
return request.post({ url: '/frontend/mini/unbindMobile', params, headersType: 'POST_PARAMS' })
}
export const saveUserInfo = (params) => {
return request.post({ url: '/frontend/mini/saveUserInfo', params, headersType: 'POST_PARAMS' })
}
小程序页面中使用
import { getUserInfo, unbindMobile, saveUserInfo } from '../../api/user/index'
// 获取用户信息
async getUserInfo (para) {
const res = await getUserInfo({})
this.setData({
userInfo: res.data
})
}