微信原生小程序请求封装

326 阅读3分钟

u=1852209176,306290716&fm=253&fmt=auto&app=138&f=JPEG.webp

背景

微信小程序作为一种轻量级的应用开发框架,已经成为许多开发者的首选。在小程序开发中,网络请求是常见的需求之一。为了提高代码的复用性和开发效率,我们可以封装网络请求,使其更加易用和灵活。本文将介绍如何在微信小程序中封装请求,让开发变得更加便捷。

封装请求的优势

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]
}

请求封装

  1. config文件下创建一个request.js文件,根据实际业务场景进行兼容修改;
  2. 封装设置了loadingCount这个参数,为了解决同个页面多个接口请求并发loading出现闪屏等问题;
  3. 请求头增加了POST_PARAMS判断,因为公司场景post请求存在参数放到query中而不是body,做了这个处理;
  4. 封装代码如下:
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
    })
}