在 UniApp 中,使用 uni.request
进行网络请求是常见的操作。为了简化请求流程,统一错误处理和响应处理,我们通常会对 uni.request
进行二次封装。二次封装后,你可以在项目中通过调用自定义的请求方法,而不必每次都手动写重复的请求配置。
本文将介绍如何创建一个通用的请求封装工具。
一、封装文件结构
我们将封装的请求方法放在一个单独的文件中,便于维护和复用。通常,这个文件可以放在 utils/request.js
路径下。
/src
├── /utils
└── request.js // 网络请求二次封装
二、封装 uni.request
2.1 基本封装
首先,我们定义一个封装的 request
函数,处理请求、响应以及错误捕获。
// /src/utils/request.js
const BASE_URL = 'https://api.example.com'; // 接口基础 URL
const TIMEOUT = 10000; // 请求超时时间(毫秒)
// 请求方法封装
const request = (options) => {
// 统一处理请求头
let headers = {
'Content-Type': 'application/json', // 默认请求内容类型
...options.headers, // 允许传入额外的请求头
};
// 如果有 token,则添加到请求头
const token = uni.getStorageSync('token');
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
return new Promise((resolve, reject) => {
uni.request({
url: BASE_URL + options.url, // 拼接基础 URL 和接口路径
method: options.method || 'GET', // 默认为 GET 请求
data: options.data || {},
header: headers,
timeout: options.timeout || TIMEOUT, // 请求超时时间
success: (res) => {
if (res.statusCode === 200) {
// 请求成功,处理返回数据
resolve(res.data);
} else {
// 请求失败,处理错误
reject(res);
}
},
fail: (err) => {
// 网络或服务器错误,统一处理
reject(err);
},
});
});
};
export default request;
2.2 请求参数说明
url
: 请求接口的路径,必须传入。method
: 请求方法,默认为GET
,也可以传POST
、PUT
等。data
: 请求的参数,可以是一个对象,传递给服务器。headers
: 可选的请求头,允许用户传递自定义请求头。timeout
: 请求超时设置,默认为 10 秒。
三、使用封装的请求方法
3.1 发送请求
在页面或其他业务逻辑中使用二次封装的 request
方法来发送请求。通过 then
和 catch
处理成功和失败的响应。
// 示例:调用封装的请求方法进行 API 请求
import request from '@/utils/request'; // 引入请求工具
export default {
data() {
return {
userInfo: null,
};
},
methods: {
// 获取用户信息接口
getUserInfo() {
request({
url: '/user/info', // 接口路径
method: 'GET', // 请求方法
})
.then((res) => {
// 成功回调,处理返回数据
this.userInfo = res.data;
})
.catch((err) => {
// 失败回调,统一错误处理
uni.showToast({
title: '请求失败',
icon: 'none',
});
});
},
},
mounted() {
this.getUserInfo();
},
};
四、添加全局请求拦截
如果你需要在每次请求前进行一些额外的操作(例如显示加载动画、请求权限等),可以在封装的 request
函数中加入拦截器。
4.1 请求前操作
在请求发送前,我们可以加一个请求的 loading 提示,通知用户正在加载数据。
const request = (options) => {
// 统一处理请求头
let headers = {
'Content-Type': 'application/json',
...options.headers,
};
const token = uni.getStorageSync('token');
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
// 显示加载动画
uni.showLoading({
title: '加载中...',
mask: true, // 遮罩层,防止用户操作
});
return new Promise((resolve, reject) => {
uni.request({
url: BASE_URL + options.url,
method: options.method || 'GET',
data: options.data || {},
header: headers,
timeout: options.timeout || TIMEOUT,
success: (res) => {
uni.hideLoading(); // 请求完成,隐藏加载动画
if (res.statusCode === 200) {
resolve(res.data);
} else {
reject(res);
}
},
fail: (err) => {
uni.hideLoading(); // 请求失败,隐藏加载动画
reject(err);
},
});
});
};
五、统一处理错误和提示
你可以在二次封装中统一处理错误信息,确保用户得到清晰的提示。
5.1 错误处理
在 request.js
中可以对不同的错误进行处理,例如网络错误、超时错误等。
const request = (options) => {
// 请求头处理
let headers = {
'Content-Type': 'application/json',
...options.headers,
};
const token = uni.getStorageSync('token');
if (token) {
headers['Authorization'] = `Bearer ${token}`;
}
return new Promise((resolve, reject) => {
uni.request({
url: BASE_URL + options.url,
method: options.method || 'GET',
data: options.data || {},
header: headers,
timeout: options.timeout || TIMEOUT,
success: (res) => {
if (res.statusCode === 200) {
resolve(res.data);
} else {
// 根据错误状态码处理
uni.showToast({
title: res.data.message || '请求失败',
icon: 'none',
});
reject(res);
}
},
fail: (err) => {
uni.showToast({
title: '网络请求失败',
icon: 'none',
});
reject(err);
},
});
});
};
六、总结
通过对 uni.request
的二次封装,我们可以统一处理请求头、参数、超时、错误提示等,使得请求代码更加简洁和规范。二次封装不仅能提高代码复用性,还能帮助你集中管理请求逻辑,提高维护性。
注意事项:
- 错误处理:务必统一错误提示,避免多个页面重复编写错误处理逻辑。
- 权限管理:对于需要登录的接口,统一管理 token 的处理,确保每次请求都带上有效的 token。
希望这篇文章能帮助大家更好地封装 UniApp 中的请求,提升开发效率