前言:
微信小程序开发中,后端提供了接口设计文档,前端可以先mock数据模拟api请求进行开发调试,而且可以根据需要设计mock文件的格式和内容,这样在后端接口开发完成之前,前端可以最大限度的完成前端的开发。
编写mock数据文件:
//mocklist.js export default { //获取openid(所有登录方式都需要有) getOpenId: { s: "0", m: "登录成功", uid: "666", d: { openid: 'ds3fs5f1sd3s5d1f3sdf153' } }, //检验登录有效性 checkToken: { s: "0", m: "登录成功", uid: "666", d: { usertoken: 'wefsdik8888888888888888888' } }, ......
为了方便接口请求的异常处理,mock数据中最好带有接口请求结果的状态字段,这样在前期页面制作、业务逻辑编码的时候就能把所有情况都进行考虑编码,这比等待后端提供接口或者临时编写demo数据要方便省事的多。
封装网络请求:
//request.js
//接口访问异常统一错误提示 const errorToast = function(msg) { wx.showToast({ title: msg || "服务器繁忙,请稍后再试", icon: "none" }) } //接口列表(如果接口较多,可以单独提取到一个js文件中) const apiList = { /*登录相关*/ checkToken: 'user/checkToken', //检查token是否有效 getSmsCode: 'user/authcode', //获取验证码 userLogin: 'user/login', //登录 ...... } /** * 封装http 请求方法 */ const apiUrl ="https://xxx.xxxx.cn/" const http = (params) => { wx.loading() //返回promise 对象 return new Promise((resolve, reject) => { wx.request({ url: apiUrl + params.url, data: params.data, header: params.header || { "Content-Type": "application/x-www-form-urlencoded", "usertoken": wx.getStorageSync("usertoken"), "uid":(new Date()).getTime()+'_'+Math.floor(Math.random()*100000000)//接口请求流水号 }, method: params.method || 'POST', success: function(res) { wx.hideLoading() var data = res.data; if (res.statusCode == 200 && data) { //需要登录、后端返回登录失效代码,需要自动登录然后重新加载小程序 if (!params.noNeedLogin && data.s == 302) { wx.removeStorageSync("usertoken") wx.removeStorageSync("openid") wx.toast('登陆失效,请重新登陆~', () => { //登陆失效,跳转到登陆页面 wx.reLaunch({ url: '../../pages/login/index', }) }) return; } //判断是否需要预处理错误信息 if (params.noPreError) { //接口需要单独处理错误信息,直接返回响应信息 resolve(data) } else { if (data.s == "0") { resolve(data.d) } else { errorToast(data.m) console.log(data) } } } else { errorToast(); console.log(data) } }, fail: function(e) { errorToast(); reject(e) } }) }) } /** * 封装mock数据模拟接口请求 */ import { mocklist } from '../mocklist.js' const http2 = (params) => { return new Promise((resolve, reject) => { wx.loading() setTimeout(() => { for (var key in apiList) { if (apiList[key] == params.url) { wx.hideLoading() var data = mocklist[key] //需要登录、后端返回登录失效代码,需要自动登录然后重新加载小程序 if (!params.noNeedLogin && data.s == 302) { wx.toast('登陆失效,请重新登陆~', () => { //登陆失效,跳转到登陆页面 wx.reLaunch({ url: '../../pages/login/index', }) }) return; } //判断是否需要预处理错误信息 if (params.noPreError) { //接口需要单独处理错误信息,直接返回响应信息 resolve(data) } else { if (data.s == "0") { resolve(data.d) } else { wx.toast(data.m || "系统繁忙,请稍后重试~") console.log(data) } } break; } } }, 500) }) } module.exports = { errorToast, apiList, http:http//http2 }
说明:
1.接口路径 apiList 如果比较多,可以单独抽取到一个js中;
2.响应数据预处理:响应数据默认进行预处理,给与统一返回响应值和异常提示;特殊接口根据noPreError、noNeedLogin进行特殊处理(后文会详细说明);
3.对于统一返回的数据是用 data 还是 data.d ,则要考虑正常情况下无需返回数据的情况(如对手机号进行验证,只需要返回正确的响应状态和提示信息,无需返回数据,即data.d为空),对大部分接口直接返回data.d的好处是页面中编写接口请求可以不需要再对data.s进行判断,直接对返回的data(也就是data.d)进行判断就好了,如果无需返回数据的接口请求比较少,则直接使用noPreError进行特殊处理就可以了;
4.分别封装了真实请求(http)和mock请求(http2),而切换也很容易。
//使用mock开发 module.exports = { http:http2 }
//后端真实接口联调 module.exports = { http:http }
对具体接口请求进行封装:
import { errorToast, apiList, http } from 'request.js' /** * 导出接口请求 * noNeedLogin: true 无需登录 * noPreError: true 无需预处理错误信息 */ module.exports = { errorToast, //检验用户登录有效性 checkToken(channelid) { return http({ url: apiList.checkToken, data: { channelid: channelid }, noPreError: true, //无需预处理错误信息 noNeedLogin: true //无需登录 }) }, //获取短信验证码 getSmsCode(phone) { return http({ url: apiList.getSmsCode, data: { phone: phone }, noNeedLogin: true }) }, ...... }
如上,接口请求封装配置了接口的地址、参数以及两个特殊参数:
noPreError:(无需预处理)参数对响应结果进行特殊处理的(特殊异常提示,跳转等)的接口请求进行标志;
noNeedLogin:无需登陆参数,仅针对无需登陆就能访问的接口进行配置。