当前位置: 首页 > news >正文

Uniapp 中 uni.request 的二次封装

Uniapp 中 uni.request 的二次封装

在 Uniapp 项目中,对 uni.request 进行二次封装可以提高代码复用性、统一处理错误和简化 API 调用。下面是一个完整的封装方案:

一、基础封装

1. 创建 request.js 工具文件

// utils/request.js// 基础配置
const config = {baseURL: process.env.VUE_APP_API_BASE_URL || '', // 从环境变量获取基础URLtimeout: 10000, // 请求超时时间header: {'Content-Type': 'application/json'}
};// 请求拦截器
const requestInterceptor = (options) => {// 添加token等全局headerconst token = uni.getStorageSync('token');if (token) {options.header = options.header || {};options.header['Authorization'] = `Bearer ${token}`;}// 可以在这里处理其他全局逻辑return options;
};// 响应拦截器
const responseInterceptor = (response, resolve, reject) => {const { statusCode, data } = response;if (statusCode === 200) {// 这里根据后端接口规范调整判断逻辑if (data.code === 0 || data.success) {resolve(data.data || data);} else {// 业务逻辑错误uni.showToast({title: data.message || '请求失败',icon: 'none'});reject(data);}} else {// HTTP错误handleHttpError(statusCode, reject);}
};// 处理HTTP错误
const handleHttpError = (statusCode, reject) => {let errMessage = '请求失败';switch (statusCode) {case 401:errMessage = '未授权,请登录';// 可以跳转到登录页break;case 403:errMessage = '拒绝访问';break;case 404:errMessage = '请求地址错误';break;case 500:errMessage = '服务器内部错误';break;default:errMessage = `网络错误 (${statusCode})`;}uni.showToast({title: errMessage,icon: 'none'});reject({ statusCode, message: errMessage });
};// 核心请求方法
const request = (options) => {return new Promise((resolve, reject) => {// 合并配置options = {...config,...options,url: config.baseURL + options.url,header: {...config.header,...(options.header || {})}};// 请求拦截options = requestInterceptor(options) || options;// 发起请求uni.request({...options,success: (res) => {responseInterceptor(res, resolve, reject);},fail: (err) => {uni.showToast({title: '网络连接失败',icon: 'none'});reject(err);},complete: () => {// 可以在这里处理loading状态等}});});
};// 导出常用方法
export default {get(url, data = {}, options = {}) {return request({url,data,method: 'GET',...options});},post(url, data = {}, options = {}) {return request({url,data,method: 'POST',...options});},put(url, data = {}, options = {}) {return request({url,data,method: 'PUT',...options});},delete(url, data = {}, options = {}) {return request({url,data,method: 'DELETE',...options});},// 原始request方法request
};

二、高级功能扩展

1. 添加取消请求功能

// 在request.js中添加const pendingRequests = new Map();// 生成请求唯一标识
const generateReqKey = (config) => {const { url, method, params = {}, data = {} } = config;return [url, method, JSON.stringify(params), JSON.stringify(data)].join('&');
};// 添加到请求拦截器
const requestInterceptor = (options) => {// ...其他拦截逻辑const reqKey = generateReqKey(options);if (pendingRequests.has(reqKey)) {const cancel = pendingRequests.get(reqKey);cancel('取消重复请求');pendingRequests.delete(reqKey);}options.cancelToken = options.cancelToken || new CancelToken((cancel) => {pendingRequests.set(reqKey, cancel);});return options;
};// 添加到响应拦截器
const responseInterceptor = (response, resolve, reject) => {const reqKey = generateReqKey(response.config);pendingRequests.delete(reqKey);// ...其他逻辑
};// CancelToken构造函数
function CancelToken(executor) {let cancel;this.promise = new Promise((resolve) => {cancel = resolve;});executor(cancel);
}// 导出取消请求方法
export const cancelRequest = (config) => {const reqKey = generateReqKey(config);if (pendingRequests.has(reqKey)) {const cancel = pendingRequests.get(reqKey);cancel('手动取消请求');pendingRequests.delete(reqKey);}
};

2. 添加请求重试机制

// 修改request方法
const request = (options, retryCount = 0) => {return new Promise((resolve, reject) => {// ...原有逻辑uni.request({// ...原有配置fail: (err) => {if (retryCount < (options.retry || 3)) {setTimeout(() => {request(options, retryCount + 1).then(resolve).catch(reject);}, 1000 * (retryCount + 1));} else {uni.showToast({title: '网络连接失败',icon: 'none'});reject(err);}}});});
};

三、使用示例

1. 基本使用

import http from '@/utils/request';// GET请求
http.get('/api/user', { id: 123 }).then(data => {console.log(data);}).catch(err => {console.error(err);});// POST请求
http.post('/api/login', { username: 'admin', password: '123456' }).then(data => {console.log(data);});

2. 带额外配置的请求

http.post('/api/upload', formData, {header: {'Content-Type': 'multipart/form-data'},timeout: 30000 // 单独设置超时时间
});

3. 取消请求

const requestTask = http.get('/api/large-data');// 需要取消时
requestTask.cancel(); // 如果实现了取消功能

四、在 Vue 中全局挂载

1. 在 main.js 中挂载

// main.js
import Vue from 'vue';
import http from '@/utils/request';Vue.prototype.$http = http;

2. 在组件中使用

// 组件内
export default {methods: {fetchData() {this.$http.get('/api/data').then(data => {// 处理数据});}}
}

五、TypeScript 支持

如果你使用 TypeScript,可以添加类型定义:

// types/request.d.ts
declare module '@/utils/request' {interface RequestConfig {url: string;method?: 'GET' | 'POST' | 'PUT' | 'DELETE';data?: any;params?: any;header?: Record<string, string>;timeout?: number;[key: string]: any;}interface ResponseData<T = any> {code: number;message: string;data: T;}interface RequestInstance {request<T = any>(config: RequestConfig): Promise<T>;get<T = any>(url: string, params?: any, config?: RequestConfig): Promise<T>;post<T = any>(url: string, data?: any, config?: RequestConfig): Promise<T>;put<T = any>(url: string, data?: any, config?: RequestConfig): Promise<T>;delete<T = any>(url: string, data?: any, config?: RequestConfig): Promise<T>;}const http: RequestInstance;export default http;
}

六、最佳实践建议

  1. 环境变量管理:将 baseURL 等配置通过环境变量管理
  2. 错误处理:根据业务需求统一处理错误码
  3. Loading状态:可以集成全局Loading状态控制
  4. Mock数据:开发环境下可以集成Mock功能
  5. 缓存策略:对某些GET请求可以添加缓存功能
  6. 性能监控:可以添加请求耗时统计等功能
  7. 日志记录:重要请求可以添加日志记录功能

这样的封装可以大大提升项目的开发效率和可维护性,同时保持足够的灵活性应对各种业务场景。

http://www.dtcms.com/a/331831.html

相关文章:

  • stm32f103rct6开发板引脚图
  • 芯伯乐1MHz高频低功耗运放芯片MCP6001/2/4系列,微安级功耗精密信号处理
  • UML函数原型中stereotype的含义,有啥用?
  • 打靶日常-CSRF
  • 中国车企全球化数字转型标杆案例:SAP系统多项目整合升级实践
  • 考研408《计算机组成原理》复习笔记,第五章(2)——CPU指令执行过程
  • Day 11: 预训练语言模型基础 - 理论精华到实战应用的完整指南
  • k8s+isulad 网络问题
  • 【奔跑吧!Linux 内核(第二版)】第7章:系统调用的概念
  • 基本电子元件:电阻器
  • 读书笔记:《我看见的世界》
  • 日志系统(log4cpp)
  • 主进程如何将客户端连接分配到房间进程
  • Android UI(一)登录注册 - Compose
  • 基于Python和Dify的成本对账系统开发
  • OpenCV Canny 边缘检测
  • 软考中级【网络工程师】第6版教材 第3章 局域网 (上)
  • Linux中tty与8250-uart的虐恋(包括双中断发送接收机制)
  • Linux中Samba服务配置与使用指南
  • YouBallin正式上线:用Web3重塑创作者经济
  • 会议通信系统核心流程详解(底稿1)
  • JVM的逃逸分析深入学习
  • 17.2 修改购物车商品
  • RLVR(可验证奖励的强化学习):大模型后训练的客观评估策略
  • 负载因子(Load Factor) :哈希表(Hash Table)中的一个关键性能指标
  • AI大模型+Meta分析:助力发表高水平SCI论文
  • 多任务并发:进程管理的核心奥秘
  • 【记录】Apache SeaTunnel 系统监控信息
  • 使用ETL工具同步Oracle的表到Doris
  • 使用load data或insert导入10w条数据