This theme is built with|

_Elaina

园龄:1年8个月粉丝:0关注:0

微信小程序TypeScript请求封装(TS+request)

  • 目录结构

         - WxApp
    
             - api 请求方式
    
                - index.ts 统一输出api接口
    
                - base.ts 环境判断
    
                - user 对应数据请求
                    - userApi.ts
    
         - utils 
             - request.ts 封装请求
    
  • 封装request

首先,我们先搞wx.request先,这个搞完,其它都是小意思,代码如下:


目录 utils/request.ts

/**
 * @description: HTTP请求方法枚举
 */
export enum HttpMethod {
	GET = 'GET',
	POST = 'POST',
	OPTIONS = 'OPTIONS',
	PUT = 'PUT',
	DELETE = 'DELETE'
}

/**
 * @description: HTTP请求配置
*/
interface RequestConfig {
	/** API路径 */
	url?: string
	/** Method类型 */
	method?: HttpMethod
	/** 接口返回数据 */
	data?: any
	/** 无TOKEN触发异常捕获时,是否执行异常逻辑 */
	needToken?: boolean
	/** Header头部 */
	header?: object
	/** 返回的数据格式 */
	dataType?: string
	/** 请求报错时,是否弹出message提示(默认弹出)*/
	noShowMsg?: boolean
}

/**
 * @description: 声明业务数据类型
*/
export interface MyAwesomeData<T> {
	code: number
	msg: string
	data: T
}

class HttpRequest {
	private static instance: HttpRequest
	private constructor() { }
	/** 请求函数(单例模式)
	*
	* **注意:**
	* `method`需使用`HttpMethod`枚举类,切勿自行定义
	*
	* **示例代码**
	* ```js
	 HttpRequest.getInstance().request({
		 url: '/Api',
		 method: HttpMethod.GET
	 })
	* ```
	*/
	public static getInstance(): HttpRequest {
		if (!this.instance) {
			this.instance = new HttpRequest()
		}
		return this.instance
	}

	// 处理请求异常状态码
	private handerErrorStatus(statusCode: number, requestConfig: RequestConfig) {
		let msg = '服务找不到'
		if (statusCode === 502 || statusCode === 503) {
			msg = '服务器开小差了~'
		}
		!requestConfig.noShowMsg && wx.showToast({
			title: `${msg},错误码:${statusCode}`,
			icon: 'none'
		})
		return msg
	}

	// 处理请求异常
	private handerError(err: { errMsg: string }, requestConfig: RequestConfig) {
		let msg = `请求异常`
		if (/timeout/.test(err.errMsg)) {
			msg = '请求超时'
		}
		!requestConfig.noShowMsg && wx.showToast({
			title: msg,
			icon: 'none'
		});
		return msg
	}

	// 服务器接口请求
	public request<T>(requestConfig: RequestConfig): Promise<MyAwesomeData<T>> {
		let _this = this
		return new Promise((resolve, reject) => {
			// 默认header
			const contentType = requestConfig.method === 'GET' ? 'application/x-www-form-urlencoded' : 'application/json'
			const header = {
				'content-type': contentType
			}
			wx.request({
				method: requestConfig.method,
				url: `${requestConfig.url}`,
				data: requestConfig.data,
				header: Object.assign(header, requestConfig?.header),
				dataType: !requestConfig.dataType ? 'json' : '其他',
				success: function (res) {
					// console.log('发送返回:', res) //res:{cookies, data, header, statusCode}
					const code = res.statusCode || -404
					const data = res.data
					/** 接口请求成功*/
					if (code == 200) {
						resolve(data as any)
					} else if (code === 401) {
						// 未授权
						!requestConfig.noShowMsg && wx.showModal({
							title: '登录失效',
							content: '登录失效,请重新登录',
						}).then(resModa => {
							if (resModa.confirm) { }
						})
						reject({ code, msg: '未登录', data: data })
					} else {
						//非200及401状态码-数据处理
						const errMsg = _this.handerErrorStatus(code, requestConfig)
						reject({ code, msg: errMsg, data })
					}
				},
				fail: err => {
					let msg = _this.handerError(err, requestConfig)
					reject({ msg })
				}
			})
		})
	}

	/**
	 * @description: get请求函数
	 * @param {string} url 请求地址
	 * @param {Object} data 请求参数
	 * @param {RequestConfig} OtherConfig request其他配置
	 * @return {*}
	 */
	public get<T>(url: string, data?: Object, OtherConfig?: RequestConfig) {
		return this.request<T>({ method: HttpMethod.GET, url, data, ...OtherConfig })
	}

	/**
	 * @description: post请求函数
	 * @param {string} url 请求地址
	 * @param {Object} data 请求参数
	 * @param {RequestConfig} OtherConfig request其他配置
	 * @return {*}
	 */
	public post<T>(url: string, data: Object, OtherConfig?: RequestConfig) {
		return this.request<T>({ method: HttpMethod.POST, url, data, ...OtherConfig })
	}

	/**
	 * @description: delete请求函数
	 * @param {string} url 请求地址
	 * @param {Object} data 请求参数
	 * @param {RequestConfig} OtherConfig request其他配置
	 * @return {*}
	 */
	public delete<T>(url: string, data: Object, OtherConfig?: RequestConfig) {
		return this.request<T>({ method: HttpMethod.DELETE, url, data, ...OtherConfig })
	}

	/**
	 * @description: put请求函数
	 * @param {string} url 请求地址
	 * @param {Object} data 请求参数
	 * @param {RequestConfig} OtherConfig request其他配置
	 * @return {*}
	 */
	public put<T>(url: string, data?: Object, OtherConfig?: RequestConfig) {
		return this.request<T>({ method: HttpMethod.PUT, url, data, ...OtherConfig })
	}

}

export const httpRequest = HttpRequest.getInstance()
  • 环境判断封装
    对环境进行封装,可自行判断,目录:/api/base.ts
/**
 * 获取小程序版本信息
 * 值有:develop(开发版)、trial(体验版)、release(正式版)
*/
const accountInfo = wx.getAccountInfoSync()
const envVersion = accountInfo.miniProgram.envVersion || 'release'

/**
   * 国地服务器
  */
const GDEnvs = {
  develop: {
    host: 'https://mock.com',
    imgHost: 'http://192.168.0.2:20087'
  },
  trial: {
    host: 'http://192.168.0.1:20086',
    imgHost: 'http://192.168.0.2:20086'
  },
  release: {
    host: 'https://XXXXX.com',
    imgHost: 'http://image.XXXXX.com'
  },
}

export class allBaseUrl {
  /**
   * 国地服务器
  */
  static GDEnvs = GDEnvs[envVersion]
}
  • 封装接口api

对接口名称进行封装,目录 /api/user/userApi.ts

import { httpRequest } from '../../utils/request'
const baseUrl = require('../base').allBaseUrl.GDEnvs.host

export default class userApi {
  /**
   * @description: post获取用户信息
   * @return {*}
   */
  static getUserInfo = (data: UserInfo) =>
    httpRequest.post<ReturnUserInfo>(
      baseUrl + '/mock/getUserInfo',
      data
    )

  /**
   * @description: get请求
   * @return {*}
   */
  static getVillageList = () =>
    httpRequest.get<VillageList>(
      baseUrl + '/mock/villageList',
    )
}
  • 接口统一输出

对封装好的api接口统一输出,这个非必要,见仁见智,目录 api/index.ts

/*
 * @Author: _Elaina
 * @Date: 2023-11-16 17:12:54
 * @LastEditTime: 2023-11-16 17:12:54
 * @LastEditors: _Elaina
 * @Description: 
 */

import userApi from './system/userApi'

class apis {
  /**
   * @description: 用户相关Api
   */
  static userApi = userApi
}

export default apis
  • 页面使用

在页面中可以直接 api/index.ts 引入使用

import $api from '../../api/index'

// 调用
$api.userApi.getUserInfo({ username: 'demo', password: '123456' }).then((res) => {
    if (res.code === 200) {
      userStore.setUserInfo(res.data.userInfo)
    }
})

转载 · https://developers.weixin.qq.com/community/develop/article/doc/000c20f9764df84e2ade643ef5b013

本文作者:_Elaina

本文链接:https://www.cnblogs.com/get-elaina/p/17836789.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   _Elaina  阅读(315)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起
  1. 1 404 not found REOL
404 not found - REOL
00:00 / 00:00
An audio error has occurred.

作曲 : Reol

作词 : Reol

fade away...do over again...

fade away...do over again...

歌い始めの一文字目 いつも迷ってる

歌い始めの一文字目 いつも迷ってる

どうせとりとめのないことだけど

伝わらなきゃもっと意味がない

どうしたってこんなに複雑なのに

どうしたってこんなに複雑なのに

噛み砕いてやらなきゃ伝わらない

ほら結局歌詞なんかどうだっていい

僕の音楽なんかこの世になくたっていいんだよ

Everybody don't know why.

Everybody don't know why.

Everybody don't know much.

僕は気にしない 君は気付かない

何処にももういないいない

Everybody don't know why.

Everybody don't know why.

Everybody don't know much.

忘れていく 忘れられていく

We don't know,We don't know.

目の前 広がる現実世界がまた歪んだ

目の前 広がる現実世界がまた歪んだ

何度リセットしても

僕は僕以外の誰かには生まれ変われない

「そんなの知ってるよ」

気になるあの子の噂話も

シニカル標的は次の速報

麻痺しちゃってるこっからエスケープ

麻痺しちゃってるこっからエスケープ

遠く遠くまで行けるよ

安定なんてない 不安定な世界

安定なんてない 不安定な世界

安定なんてない きっと明日には忘れるよ

fade away...do over again...

fade away...do over again...

そうだ世界はどこかがいつも嘘くさい

そうだ世界はどこかがいつも嘘くさい

綺麗事だけじゃ大事な人たちすら守れない

くだらない 僕らみんなどこか狂ってるみたい

本当のことなんか全部神様も知らない

Everybody don't know why.

Everybody don't know why.

Everybody don't know much.

僕は気にしない 君は気付かない

何処にももういないいない

Everybody don't know why.

Everybody don't know why.

Everybody don't know much.

忘れていく 忘れられていく

We don't know,We don't know.