更新记录
2.0.5(2026-07-22)
下载此版本
新增
- 完成拦截器:新增
useComplete 方法,在请求最终完成时执行(无论成功或失败,对应 uni.request 的 complete 回调)
- 捕获超时、断网、DNS 解析失败、CORS 拦截等所有异常场景
- 支持异步操作(
async/await)
- 统一在
interceptors.complete 中管理,与 useRequest / useResponse 风格一致
类型
- 新增
CompleteInterceptor 类型定义
修复
2.0.4(2026-07-18)
下载此版本
新增
- 文档新增「插件生态」章节:说明插件化架构的设计理念及核心优势(核心零污染、按需加载、灵活组合、易于扩展、即插即用)
- 插件列表:展示
mh-token-refresh 插件(Token 无感刷新),提供功能描述及链接
优化
- 更正
PluginItem 接口中 config 字段注释:明确说明不传时插件函数第三个参数为 undefined,消除误导
- 完善
README.md 文档结构,提升文档完整性
2.0.3(2026-07-15)
下载此版本
优化
- 优化 README.md 特性描述,增加图标展示,提升文档可读性
查看更多
平台兼容性
uni-app(3.8.1)
| Vue2 |
Vue3 |
Chrome |
Safari |
app-vue |
app-nvue |
Android |
iOS |
鸿蒙 |
| √ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
| 微信小程序 |
支付宝小程序 |
抖音小程序 |
百度小程序 |
快手小程序 |
京东小程序 |
鸿蒙元服务 |
QQ小程序 |
飞书小程序 |
小红书小程序 |
快应用-华为 |
快应用-联盟 |
| √ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
√ |
uni-app x(3.8.1)
| Chrome |
Safari |
Android |
iOS |
鸿蒙 |
微信小程序 |
| √ |
√ |
√ |
√ |
√ |
√ |
mh-request
基于 uni-app 的网络请求封装,开箱即用,一站式解决所有请求需求。
特性
- 🚀 一行代码搞定:
GET / POST / 上传 / 下载,一个实例全搞定
- ⚡ 异步拦截器:
Token 注入、日志记录等操作轻松实现
- 🎯 智能 Loading:多请求自动叠加 / 隐藏,告别闪烁问题
- 📨 消息队列机制:多个提示按序显示,避免弹窗重叠/闪烁
- 🛡️ 开箱即用的错误处理:
HTTP 状态码映射 + 静默码支持
- 🔌 插件化架构:
Token 管理、埋点上报等能力即插即用
- 🎨 完全自定义:
Toast / Loading / Modal 全部可替换
- 🔧 字段映射:适配不同后端的
code / msg / data 命名规范
- 💎 极简零依赖:只依赖
uni-app 原生 API,无额外包体积负担
- 🔒 零污染:不使用全局拦截器,每个实例独立,互不影响
- 📦 TypeScript 优先:完整的类型提示,编码更安心
快速开始
创建请求实例
import { Request } from '@/uni_modules/mh-request'
// 默认实例
const request = new Request({
baseURL: 'https://api.example.com',
successCode: 1,
silentCodes: [409]
})
export default request
多实例配置
import { Request } from '@/uni_modules/mh-request'
// 用户相关接口(带 Token)
const userRequest = new Request({
baseURL: 'https://api.example.com',
successCode: 1,
plugins: [{ plugin: tokenPlugin }]
})
// 公开接口(无需 Token)
const publicRequest = new Request({
baseURL: 'https://public.example.com',
successCode: 0
})
export { userRequest, publicRequest }
发送请求
// 定义具体业务数据类型
interface UserInfo {
id: number
name: string
avatar: string
}
// GET 请求
const res = await request.get<UserInfo>('/user/info')
console.log(res.name)
// POST 请求
const res = await request.post('/user/login', { username: 'admin', password: '123456' })
// 完整配置
const res = await request.request({
url: '/user/info',
method: 'GET',
data: { id: 1 },
showLoading: true,
showSuccessMessage: true
})
文件上传
const res = await request.upload({
url: '/upload',
filePath: tempFilePath,
name: 'file',
formData: { type: 'image' }
})
文件下载
const res = await request.download({ url: 'https://example.com/file.pdf' })
console.log(res.tempFilePath)
请求拦截器
request.useRequest(async (options) => {
const token = uni.getStorageSync('token')
if (token) {
options.header = { ...options.header, Authorization: `Bearer ${token}` }
}
})
响应拦截器
request.useResponse(async (res, options, data) => {
if (data?.code === 401) {
uni.removeStorageSync('token')
uni.reLaunch({ url: '/pages/login/index' })
}
})
完成拦截器
request.useComplete(async (res, options) => {
// res 包含请求的最终结果
if (res.errMsg) {
// 网络错误:超时、断网、DNS 解析失败、CORS 拦截等
console.warn('请求失败:', options.url, res.errMsg)
} else {
// 请求完成(无论业务是否成功)
console.log('请求完成:', options.url, res.statusCode)
}
})
取消请求
let task
request.get('/user/info', { onTask: (t) => (task = t) })
task?.abort()
插件扩展
// 插件函数:接收请求实例、全局配置和插件专属配置
const myPlugin = (request, config, pluginConfig) => {
// config 为全局配置
// pluginConfig 为插件专属配置(可选)
request.useRequest((options) => {
console.log('请求:', options.url)
console.log('全局配置:', config)
console.log('插件配置:', pluginConfig)
})
request.useResponse((res, options, data) => {
console.log('响应:', data)
})
}
const request = new Request({
baseURL: 'https://api.example.com',
plugins: [
{ plugin: myPlugin }, // 不传插件专属配置
{ plugin: myPlugin, config: { timeout: 5000 } } // 传入插件专属配置
]
})
自定义提示示例
import { Request } from '@/uni_modules/mh-request'
const request = new Request({
baseURL: 'https://api.example.com',
// 自定义 Toast
showToast: (title) => {
uni.showToast({ title, icon: 'none', duration: 2000 })
},
// 自定义 Loading
showLoading: (title) => {
uni.showLoading({ title, mask: true })
},
// 自定义隐藏 Loading
hideLoading: () => {
uni.hideLoading()
},
// 自定义模态弹窗
showModal: (content) => {
uni.showModal({ title: '提示', content, showCancel: false })
}
})
export default request
插件生态
为什么设计插件模式?
mh-request 采用插件化架构,核心设计理念是保持核心精简、能力按需扩展:
- 核心零污染:
Request 核心只负责请求、拦截器、Loading 和消息队列等基础能力,不内置任何业务逻辑(如 Token 管理、埋点上报等),避免核心代码臃肿。
- 按需加载:只引入实际用到的插件,未使用的插件不会进入打包产物,控制包体积。
- 灵活组合:同一实例可叠加多个插件,不同实例可加载不同插件组合,互不干扰。
- 易于扩展:插件仅需一个函数即可开发,团队可轻松封装通用能力,形成内部插件库。
- 即插即用:插件可独立发布和维护,升级回滚互不影响。
插件列表
更多插件正在开发中,敬请期待。
配置说明
构造配置
| 属性 |
类型 |
默认值 |
说明 |
| baseURL |
string |
'' |
请求基础 URL |
| successCode |
number |
1 |
业务成功状态码 |
| silentCodes |
number[] |
[409] |
静默错误码 |
| httpSuccessCodes |
number[] |
[200] |
HTTP 成功状态码 |
| plugins |
PluginItem[] |
[] |
插件列表 |
| timeout |
number |
60000 |
全局请求超时时间(毫秒),请求级 timeout 优先级更高 |
| showToast |
(title: string) => void |
uni.showToast |
自定义 Toast 提示,参数 title 为提示内容 |
| showLoading |
(title: string) => void |
uni.showLoading |
自定义加载提示,参数 title 为加载文字 |
| hideLoading |
() => void |
uni.hideLoading |
自定义隐藏加载提示 |
| showModal |
(content: string) => void |
uni.showModal |
自定义模态弹窗,参数 content 为弹窗内容 |
| apiFieldMap |
{ code: string; msg: string; data: string } |
{ code: 'code', msg: 'msg', data: 'data' } |
响应字段映射,适配不同后端的字段命名 |
请求配置
| 属性 |
类型 |
默认值 |
说明 |
| showLoading |
boolean |
false |
显示 Loading |
| showSuccessMessage |
boolean |
false |
显示成功提示 |
| showCodeMessage |
boolean |
true |
显示业务错误提示 |
| showErrorMessage |
boolean |
true |
显示 HTTP 错误提示 |
| onTask |
function |
- |
获取任务对象 |