uView Pro

23:52项目集成了 uView Pro 的 HTTP 请求模块,提供了便捷的网络请求解决方案,包含请求/响应拦截、Loading 和 Toast 提示等功能。
在 src/common/http.interceptor.ts 中配置全局的 HTTP 设置:
import type { RequestConfig, RequestInterceptor, RequestMeta, RequestOptions } from 'uview-pro'
// 配置 API 基础地址
const baseUrl = 'https://your-api.com'
// 全局请求配置
const httpRequestConfig: RequestConfig = {
baseUrl,
header: {
'content-type': 'application/json',
},
timeout: 50000, // 超时时间(毫秒)
meta: {
originalData: true, // 返回原始数据
toast: true, // 显示 toast 提示
loading: true, // 显示 loading 动画
},
}
// 请求/响应拦截器
const httpInterceptor: RequestInterceptor = {
request: (config: RequestOptions) => {
// 可以在这里添加 token、自定义 header 等
if (token) {
config.header.Authorization = `Bearer ${token}`
}
return config
},
response: async (response: any) => {
// 处理响应数据
return response
},
}import uViewPro, { httpPlugin } from 'uview-pro'
import { httpRequestConfig, httpInterceptor } from '@/common/http.interceptor'
export function createApp() {
const app = createSSRApp(App)
// 注册uView-pro
app.use(uViewPro)
// 注册http插件
app.use(httpPlugin, {
interceptor: httpInterceptor,
requestConfig: httpRequestConfig
})
return { app }
}import { http } from 'uview-pro'
// 发起 GET 请求
const fetchUserList = async () => {
try {
const res = await http.get('/api/users')
console.log('用户列表:', res)
} catch (error) {
console.error('请求失败:', error)
}
}import { http } from 'uview-pro'
const createUser = async () => {
try {
const res = await http.post('/api/users', {
name: '张三',
email: 'zhangsan@example.com'
})
console.log('创建成功:', res)
} catch (error) {
console.error('创建失败:', error)
}
}import { http } from 'uview-pro'
const updateUser = async (id: string) => {
try {
const res = await http.put(`/api/users/${id}`, {
name: '李四',
email: 'lisi@example.com'
})
console.log('更新成功:', res)
} catch (error) {
console.error('更新失败:', error)
}
}import { http } from 'uview-pro'
const deleteUser = async (id: string) => {
try {
const res = await http.delete(`/api/users/${id}`)
console.log('删除成功:', res)
} catch (error) {
console.error('删除失败:', error)
}
}可以在单个请求中覆盖全局配置:
import { http } from 'uview-pro'
// 关闭 Loading 提示
const fetchData = async () => {
const res = await http.get('/api/data', {}, {
meta: {
loading: false, // 不显示 loading
toast: true // 显示 toast
}
})
}
// 自定义超时
const slowRequest = async () => {
const res = await http.get('/api/slow-api', {}, {
timeout: 30000 // 30 秒超时
})
}
// 自定义 Header
const sendToken = async (token: string) => {
const res = await http.get('/api/protected', {}, {
header: {
'Authorization': `Bearer ${token}`
}
})
}创建 src/api/useUserApi.ts:
import { http } from 'uview-pro'
import { ref } from 'vue'
export function useUserApi() {
const users = ref([])
const loading = ref(false)
// 获取用户列表
const fetchUsers = async () => {
loading.value = true
try {
const res = await http.get<any>('/api/users')
users.value = res.data
}
finally {
loading.value = false
}
}
// 创建用户
const createUser = async (data: any) => {
return await http.post('/api/users', data)
}
// 更新用户
const updateUser = async (id: string, data: any) => {
return await http.put(`/api/users/${id}`, data)
}
// 删除用户
const deleteUser = async (id: string) => {
return await http.delete(`/api/users/${id}`)
}
return {
users,
loading,
fetchUsers,
createUser,
updateUser,
deleteUser,
}
}在组件中使用:
<script setup lang="ts">
import { useUserApi } from '@/api/useUserApi'
const { users, loading, fetchUsers } = useUserApi()
onMounted(() => {
fetchUsers()
})
</script>
<template>
<view v-if="loading" class="loading">加载中...</view>
<view v-else class="user-list">
<view v-for="user in users" :key="user.id" class="user-item">
{{ user.name }}
</view>
</view>
</template>import { http } from 'uview-pro'
const uploadFile = async (filePath: string) => {
try {
const res = await http.upload('/api/upload', {
filePath,
name: 'file'
})
console.log('上传成功:', res)
} catch (error) {
console.error('上传失败:', error)
}
}import { http } from 'uview-pro'
// 发起多个并发请求
const fetchDashboard = async () => {
try {
const [users, posts, comments] = await Promise.all([
http.get('/api/users'),
http.get('/api/posts'),
http.get('/api/comments')
])
console.log('仪表盘数据:', { users, posts, comments })
} catch (error) {
console.error('数据加载失败:', error)
}
}在 HTTP 拦截器中处理常见错误:
import { $u } from 'uview-pro'
const httpInterceptor: RequestInterceptor = {
response: async (response: any) => {
const { statusCode, data: rawData, errMsg } = response
// 处理网络错误
if (errMsg?.includes('Failed to connect')) {
showToast('网络连接失败', 'error')
throw new Error('网络错误')
}
// 处理 HTTP 状态码
if (statusCode === 401) {
// 处理未授权(可能需要重新登录)
uni.redirectTo({ url: '/pages/login/login' })
}
if (statusCode === 403) {
$u.toast('没有权限访问', 'error')
}
if (statusCode >= 500) {
$u.toast('服务器错误,请稍后重试', 'error')
}
return rawData
}
}import { http } from 'uview-pro'
const fetchData = async () => {
try {
const res = await http.get('/api/data')
// 处理成功
} catch (error) {
// 处理错误
if (error instanceof NetworkError) {
console.error('网络错误:', error.message)
} else if (error instanceof TimeoutError) {
console.error('请求超时:', error.message)
} else {
console.error('未知错误:', error)
}
}
}import { useUserStore } from '@/stores/user'
const httpInterceptor: RequestInterceptor = {
request: (config: RequestOptions) => {
const userStore = useUserStore()
if (userStore.token) {
config.header.Authorization = `Bearer ${userStore.token}`
}
return config
}
}const httpInterceptor: RequestInterceptor = {
request: (config: RequestOptions) => {
if (__DEV__) {
console.log('📤 请求:', config.url, config.data)
}
return config
},
response: async (response: any) => {
if (__DEV__) {
console.log('📥 响应:', response.config.url, response.data)
}
return response
}
}在真机调试时,可以使用:
