在Vue项目开发中,数据请求与分页逻辑是高频出现的需求。如果每个页面都重复编写请求配置、错误处理和分页状态管理,不仅效率低下,还会导致代码冗余。
一、请求核心封装:useRequest.ts
该文件是对axios的二次封装,聚焦于统一请求配置、拦截器处理和多类型请求方法封装,为整个项目提供基础请求能力。
1. 结构解析
// 核心结构概览
export default function useRequest() {
// 1. 创建axios实例,配置基础参数
const instance = axios.create({...})
// 2. 请求拦截器:统一添加token
instance.interceptors.request.use(...)
// 3. 响应拦截器:统一处理错误(尤其是登录失效)
instance.interceptors.response.use(...)
// 4. 封装各类请求方法(get/post/delete/文件上传等)
const getAction = (...) => {...}
const postAction = (...) => {...}
// ...其他方法
// 5. 暴露请求方法
return { ... }
}
2. 核心优点
统一请求配置
通过axios.create集中配置baseURL(从环境变量获取,便于多环境切换)和超时时间(10秒),避免分散配置导致的维护成本。请求拦截器自动携带token
所有请求通过拦截器自动在headers中添加X-Access-Token,无需在每个请求中手动处理,确保身份验证的一致性。-
响应拦截器统一错误处理
- 针对
401状态码或Token失效信息,自动提示“登录信息失效”,2秒后跳转登录页并清除用户状态,避免手动编写重复的权限校验逻辑。 - 服务器异常时返回标准化错误结构(
{success: false, message: '...'}),简化业务层的错误判断。
- 针对
-
多场景请求方法封装
除了基础的getAction、postAction,还针对特殊场景封装:-
arrayAction:支持以数组为参数的POST请求; -
fileAction/multiFileAction:处理单文件/多文件上传(自动设置multipart/form-data类型,超时时间设为1小时); -
streamAction:处理流数据(如文件下载,设置responseType: 'arraybuffer')。
-
二、分页逻辑封装:useQueryPage.ts
基于useRequest的基础能力,进一步封装分页查询逻辑,专注于分页状态管理和自动请求触发。
1. 结构解析
// 核心结构概览
export default function useQueryPage<T>(options: Options) {
// 1. 定义分页状态(页码、页大小、总数、列表数据等)
const pageNum = ref(...)
const pageSize = ref(...)
const list = ref<Array<T>>([])
// ...其他状态
// 2. 分页查询方法
const handleQueryPage = async () => {...}
// 3. 监听页码/页大小变化,自动触发查询
watch([pageNum, pageSize], (...) => {
handleQueryPage()
})
// 4. 暴露状态和方法
return { ... }
}
2. 核心优点
分页状态自动化管理
内置pageNum(当前页)、pageSize(每页条数)、total(总条数)等核心分页参数,无需在组件中重复定义,通过ref实现响应式更新。自动触发查询逻辑
通过watch监听pageNum和pageSize的变化,当页码或页大小改变时自动调用handleQueryPage,避免在组件中手动绑定事件(如分页器的current-change)。-
加载状态与回调机制
- 提供
loading状态,便于在组件中控制加载动画显示; - 支持
onSuccess/onFail/onError/onComplete回调,灵活处理查询成功、失败、错误和完成后的逻辑(如特殊数据格式化、提示信息)。
- 提供
类型化支持
采用泛型T定义列表数据类型(list: ref<Array<T>>),配合TypeScript可实现分页数据的类型校验,提升代码健壮性。参数灵活扩展
支持通过options.params传递额外查询参数,与分页参数(pageNum/pageSize)自动合并,无需手动拼接。
三、整体价值与使用场景
这两个文件形成了“基础请求层+业务逻辑层”的分层封装:
-
useRequest.ts解决“怎么发请求”的问题,统一处理身份验证、错误拦截、特殊请求类型; -
useQueryPage.ts解决“怎么高效处理分页”的问题,简化分页状态管理和联动逻辑。
适用场景:
- 中后台管理系统(高频分页需求);
- 需要统一身份验证和错误处理的项目;
- 包含文件上传、流数据处理的复杂场景。
使用示例:
// 在组件中使用
const { list, pageNum, pageSize, total, handleQueryPage, loading } = useQueryPage<ItemType>({
url: '/api/list',
pageSize: 10,
params: { status: 'active' },
onSuccess: (res) => { console.log('查询成功', res) }
})
通过这种封装,既能减少重复代码,又能保证项目中请求逻辑的一致性,非常适合团队协作和项目维护。同行可以根据自身项目需求,调整基础URL、错误提示文案或分页参数名(如部分后端用page/size而非pageNum/pageSize),快速适配到自己的项目中。