uniapp 请求接口封装和使用

1. 基础请求封装

javascript 复制代码
// utils/request.js
// 请求基础配置
const BASE_URL = 'http://localhost:90'; // 后端服务IP和端口

// 请求拦截器
const requestInterceptor = {
	invoke(options) {
		// 添加 token 等全局参数
		const token = uni.getStorageSync('token')
		if (token) {
			options.header = {
				...options.header,
				'Authorization': `Bearer ${token}`
			}
		}

		// 显示加载提示
		if (options.loading !== false) {
			uni.showLoading({
				title: options.loadingText || '加载中...',
				mask: true
			})
		}

		return options
	}
}

// 响应拦截器
const responseInterceptor = {
	success: (res) => {
		// 隐藏加载提示
		uni.hideLoading()
		const {
			statusCode,
			data
		} = res
		console.log("responseInterceptor success", data);
		if (statusCode === 200) {
			// 根据后端返回结构进行调整
			if (data.code === 200 || data.success) {
				return Promise.resolve(data)
			} else {
				// 业务错误
				uni.showToast({
					title: data.message || data.msg || '请求失败',
					icon: 'none'
				})
				return Promise.reject(data)
			}
		} else {
			// HTTP 错误
			handleHttpError(statusCode)
			return Promise.reject(res)
		}
	},

	fail: (error) => {
		console.log("responseInterceptor error", error);
		uni.hideLoading()
		handleNetworkError(error)
		return Promise.reject(error)
	}
}

// 处理 HTTP 错误
function handleHttpError(statusCode) {
	const errorMap = {
		400: '请求错误',
		401: '未授权,请重新登录',
		403: '拒绝访问',
		404: '请求地址不存在',
		500: '服务器内部错误',
		502: '网关错误',
		503: '服务不可用'
	}

	const message = errorMap[statusCode] || `网络请求错误 (${statusCode})`
	uni.showToast({
		title: message,
		icon: 'none'
	})
}

// 处理网络错误
function handleNetworkError(error) {
	let message = '网络连接失败'

	if (error.errMsg && error.errMsg.includes('timeout')) {
		message = '网络请求超时'
	} else if (error.errMsg && error.errMsg.includes('fail')) {
		message = '网络连接失败,请检查网络'
	}

	uni.showToast({
		title: message,
		icon: 'none'
	})
}

// 核心请求方法
function request(options) {
	// 合并配置
	const config = {
		url: options.url.startsWith('http') ? options.url : `${BASE_URL}${options.url}`,
		method: options.method || 'GET',
		data: options.data || {},
		header: options.header || {},
		timeout: options.timeout || 10000,
		loading: options.loading !== false,
		loadingText: options.loadingText || '加载中...'
	}

	// 执行请求拦截器
	const finalOptions = requestInterceptor.invoke(config)

	return new Promise((resolve, reject) => {
		uni.request({
			...finalOptions,
			success: (res) => {
				responseInterceptor.success(res)
					.then(resolve)
					.catch(reject)
			},
			fail: (error) => {
				responseInterceptor.fail(error)
					.catch(reject)
			}
		})
	})
}

// 快捷方法
const http = {
	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
		})
	},

	upload(url, filePath, formData = {}, options = {}) {
		return new Promise((resolve, reject) => {
			uni.uploadFile({
				url: `${BASE_URL}${url}`,
				filePath,
				name: options.name || 'file',
				formData,
				header: {
					'Authorization': `Bearer ${uni.getStorageSync('token')}`,
					...options.header
				},
				success: (res) => {
					if (res.statusCode === 200) {
						const data = JSON.parse(res.data)
						resolve(data)
					} else {
						reject(res)
					}
				},
				fail: reject
			})
		})
	}
}
export default http

2. API 接口统一管理

javascript 复制代码
// 引入 request 文件
import http from '@/utils/request';

// 检测版本是否更新
export function checkAppVersion(params) {
	return http.get('/demo', params)
}

3. 页面使用(VUE3写法)

javascript 复制代码
// app.vue
<script setup>
	import {
		onLaunch
	} from '@dcloudio/uni-app'

	import {
		checkAppVersion
	} from "@/api/upgrade.js";

	// 只能在App.vue里监听应用的生命周期,在其它页面监听无效
	onLaunch(() => {
		checkVersionUpdate();
	})
	const checkVersionUpdate = () => {
		// #ifdef APP-PLUS
		const systemInfo = uni.getSystemInfoSync(); // manifest.json 中的相关版本信息 
		console.log("当前版本信息", systemInfo);
		// #endif
		const params = {
			version: systemInfo.appVersion, // 当前版本号
		};
		// 检测版本是否更新
		checkAppVersion(params).then(res => {
			// 逻辑代码
		}).catch(err => {
			console.log("err", err);
		})
	}
</script>

总结:

  • 统一的错误处理 - 自动处理网络错误和业务错误
  • 自动添加 Token - 请求时自动携带认证信息
  • 加载状态管理 - 可配置的加载提示
  • 快捷方法 - 提供 GET、POST、PUT、DELETE 等快捷方式
  • 文件上传 - 封装了文件上传功能
  • 类型安全 - 统一的 API 管理,便于维护
  • 可扩展性 - 支持自定义拦截器和配置
相关推荐
by__csdn7 小时前
Vue3 setup()函数终极攻略:从入门到精通
开发语言·前端·javascript·vue.js·性能优化·typescript·ecmascript
一条可有可无的咸鱼8 小时前
企业招聘信息,企业资讯进行公示
java·vue.js·spring boot·uni-app
lionliu05198 小时前
js的扩展运算符的理解
前端·javascript·vue.js
老前端的功夫10 小时前
Vue 3 vs Vue 2 深度解析:从架构革新到开发体验全面升级
前端·vue.js·架构
狗哥哥11 小时前
Vue 3 动态菜单渲染优化实战:从白屏到“零延迟”体验
前端·vue.js
青青很轻_11 小时前
Vue自定义拖拽指令架构解析:从零到一实现元素自由拖拽
前端·javascript·vue.js
蜗牛攻城狮11 小时前
Vue 中 `scoped` 样式的实现原理详解
前端·javascript·vue.js
q_191328469512 小时前
基于SpringBoot2+Vue2的行业知识答题考试系统
java·vue.js·spring boot·mysql·毕业设计·计算机毕业设计·演示文稿
方安乐13 小时前
vue3 el-select懒加载以及自定义指令
javascript·vue.js·elementui
老华带你飞13 小时前
二手商城|基于springboot 二手商城系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·spring