在使用 uni-app 开发跨平台应用时,设计一套清晰、统一、可扩展的网络请求模块 是前期架构的关键环节。良好的请求模块不仅提高开发效率,更是保证后期维护、调试和业务扩展的基础。
一、网络请求设计目标
在uni-app中设计网络请求模块,应遵循以下架构目标:
统一封装:所有请求通过同一个方法(如
request()
)进行发送。自动鉴权:自动注入 Token,无需在业务层重复设置。
灵活配置:支持切换环境(如 dev、test、prod)。
错误处理统一:集中处理错误码、跳转登录、弹出提示等逻辑。
支持扩展:支持文件上传、分页加载、Loading 等通用特性。
二、基础结构设计
1. 环境变量与基础配置
let baseUrl = "";
let fileUrl = "";
const env = "pro"; // 可通过 process.env.NODE_ENV 自动注入
if (env === "dev") {
baseUrl = 'http://localhost:8001';
fileUrl = 'http://localhost:8001/oss/upload';
} else if (env === "pro") {
baseUrl = 'https://api.xxx.com';
fileUrl = 'https://api.xxx.com/oss/upload';
}
✅ 建议将
env
与 URL 提取为独立 config 文件进行统一管理。
2. 通用请求封装
const request = (url, method = 'GET', data = {}, header = {}) => {
header["Authorization"] = uni.getStorageSync("token") || "";
data.shop = 10;
if (data.filters) {
data.filters.shopId = 10;
}
return new Promise((resolve, reject) => {
uni.request({
url: baseUrl + url,
method,
data,
header,
success: (res) => {
if (res.data.code === 401) {
// token 失效跳转
uni.reLaunch({ url: "/pages/login/index" });
return;
}
resolve(res.data);
},
fail: () => {
reject({ code: 500, msg: "请求失败" });
}
});
});
};
✅ 核心在于:统一加 token、处理错误码、自动拼接 baseUrl。
3. 衍生方法封装
export const post = (url, param) => {
return request(url, "POST", param, {
'Content-Type': 'application/json'
});
};
export const form = (url, param) => {
return request(url, "POST", param, {
'Content-Type': 'application/x-www-form-urlencoded'
});
};
✅ 业务层只需调用
post()
或form()
,无需关心请求细节。
三、数据加载封装
1. 单条数据加载
export const one = (model, param = {}) => {
return post("/data/selectOne", {
model,
filters: param
});
};
2. 列表数据加载
export const list = (model, param = {}) => {
return post("/data/list", {
model,
filters: param
});
};
3. 响应式数据绑定封装
结合 ref
实现组件中自动数据绑定:
export const loadData = async (model, param, refObj) => {
const res = await one(model, param);
if (res.code === 200) {
refObj.value = res.data || {};
}
};
export const loadList = async (model, param, refList) => {
const res = await list(model, param);
if (res.code === 200) {
refList.value = res.data || [];
}
};
四、生命周期集成封装
针对 onLoad
和 onShow
生命周期进行响应式加载封装:
export function useLoadData(model, searchObject) {
const data = ref({});
onLoad(async () => await refresh());
const refresh = async () => {
const res = await one(model, searchObject.value);
if (res.code === 200) data.value = res.data;
};
return { data, refresh };
}
export function useShowList(model, searchObject) {
const listData = ref([]);
onShow(async () => await refresh());
const refresh = async () => {
const res = await list(model, searchObject.value);
if (res.code === 200) listData.value = res.data;
};
return { listData, refresh };
}
✅ 通过组合式函数(composition API)提升复用性和可维护性。
五、文件上传封装
export const uploadFile = (filePath) => {
return new Promise((resolve, reject) => {
uni.uploadFile({
url: fileUrl,
filePath,
name: 'file',
formData: { user: 'test' },
header: {
"Authorization": uni.getStorageSync("token")
},
success: (res) => resolve(JSON.parse(res.data)),
fail: () => reject({ code: 500, msg: "上传失败" })
});
});
};
六、登录处理封装(微信登录示例)
export const login = () => {
return new Promise((resolve, reject) => {
uni.login({
provider: 'weixin',
success: res => resolve(res),
fail: () => reject("获取信息失败")
});
});
};
七、模块导出管理
统一导出接口,方便引用:
export default {
request,
form,
post,
uploadFile,
login,
loadPostData,
loadFormData,
loadPostCallback
};
八、总结:架构设计建议
模块 | 说明 |
---|---|
config.js | 管理环境变量与 baseUrl |
request.js | 封装核心 request 与衍生方法 |
api.js | 定义业务接口:如 one/list |
hooks/useLoadList.js | 生命周期数据钩子封装 |
auth.js | 鉴权与登录逻辑管理 |
upload.js | 封装文件上传 |
九、结语
通过统一的网络请求模块封装,可以显著提升 uni-app 项目的可维护性、安全性和开发效率。随着业务发展,可进一步扩展如:
请求缓存与去重
自动重试机制
Loading 控制
全局错误提示(Toast)