2026/5/14 5:08:25
网站建设
项目流程
廊坊网站制作设计,seo技巧,企业网app下载,网站建设的要求有哪些方面在 Vue 项目开发中#xff0c;网络请求是核心环节之一。Axios 作为一款功能强大的 HTTP 客户端#xff0c;是 Vue 生态中最常用的请求工具#xff0c;但直接在业务代码中零散使用 Axios 会导致代码冗余、维护困难#xff0c;且难以统一处理请求 / 响应拦截、错误捕获等通用…在 Vue 项目开发中网络请求是核心环节之一。Axios 作为一款功能强大的 HTTP 客户端是 Vue 生态中最常用的请求工具但直接在业务代码中零散使用 Axios 会导致代码冗余、维护困难且难以统一处理请求 / 响应拦截、错误捕获等通用逻辑。本文将详细讲解如何优雅地封装 Axios结合 Vue 实现请求拦截、响应拦截、统一错误处理让网络请求层更规范、可维护。一、前置准备安装 Axios首先在 Vue 项目中安装 Axios适用于 Vue2/Vue3# npm npm install axios --save # yarn yarn add axios # pnpm pnpm add axios二、核心封装创建 Axios 实例我们先创建一个独立的请求封装文件如src/utils/request.js通过创建 Axios 实例而非直接使用全局 Axios可避免不同请求配置相互污染同时便于定制化配置。基础配置创建实例import axios from axios // 创建Axios实例 const service axios.create({ // 基础请求地址可通过环境变量配置区分开发/生产环境 baseURL: import.meta.env.VITE_API_BASE_URL || /api, // 请求超时时间 timeout: 10000, // 请求头默认配置 headers: { Content-Type: application/json;charsetutf-8 } }) export default service环境变量配置建议在 Vue3Vite 项目中创建.env.development和.env.production文件区分环境# .env.development VITE_API_BASE_URL http://localhost:3000/api # .env.production VITE_API_BASE_URL https://prod-api.example.com/api三、拦截器统一处理请求 / 响应Axios 的拦截器分为请求拦截器request和响应拦截器response可在请求发送前、响应返回后执行通用逻辑是封装的核心。1. 请求拦截器添加 Token、处理请求参数请求拦截器常用于给请求头添加认证 Token如 JWT统一处理请求参数如序列化、添加公共参数显示加载中状态如 Loading 弹窗。// 续接上面的request.js import { ElMessage } from element-plus // Vue3Element PlusVue2可改用Element UI import { useUserStore } from /stores/user // Pinia存储TokenVue2可改用Vuex // 请求拦截器 service.interceptors.request.use( (config) { // 1. 添加认证Token const userStore useUserStore() if (userStore.token) { config.headers.Authorization Bearer ${userStore.token} } // 2. GET请求参数序列化可选 if (config.method get config.params) { // 可自定义参数处理逻辑如过滤空值 config.params Object.fromEntries( Object.entries(config.params).filter(([_, v]) v ! undefined v ! null v ! ) ) } // 3. 显示加载中示例 // loadingInstance ElLoading.service({ text: 请求中... }) return config }, (error) { // 请求发送失败时的处理 // loadingInstance?.close() // 关闭加载 ElMessage.error(请求发送失败请检查网络) return Promise.reject(error) } )2. 响应拦截器统一处理响应、捕获业务错误响应拦截器常用于统一解析响应数据剥离外层包装只返回业务数据处理 HTTP 状态码错误如 401、403、500关闭加载中状态统一提示业务错误。// 续接request.js service.interceptors.response.use( (response) { // 关闭加载中 // loadingInstance?.close() // 假设后端返回格式{ code: 200, data: {}, msg: 成功 } const { code, data, msg } response.data // 业务成功 if (code 200) { return data // 只返回核心数据简化业务代码 } // 业务失败如参数错误、权限不足等 ElMessage.error(msg || 请求失败) return Promise.reject(new Error(msg || 请求失败)) }, (error) { // 关闭加载中 // loadingInstance?.close() // 处理HTTP状态码错误 const status error.response?.status let errorMsg 网络异常请稍后重试 switch (status) { case 401: errorMsg 登录失效请重新登录 // 清除Token并跳转到登录页 const userStore useUserStore() userStore.clearToken() window.location.href /login break case 403: errorMsg 暂无权限访问该资源 break case 404: errorMsg 请求的资源不存在 break case 500: errorMsg 服务器内部错误 break default: errorMsg error.response?.data?.msg || errorMsg } ElMessage.error(errorMsg) return Promise.reject(error) } )四、业务请求封装按模块分类封装好基础请求实例后建议按业务模块如用户、商品、订单创建请求文件让代码结构更清晰。示例src/api/user.jsimport request from /utils/request /** * 用户登录 * param {Object} data - 登录参数username/password */ export const login (data) { return request({ url: /user/login, method: post, data }) } /** * 获取用户信息 */ export const getUserInfo () { return request({ url: /user/info, method: get }) } /** * 修改用户信息 * param {Object} data - 用户信息 */ export const updateUserInfo (data) { return request({ url: /user/info, method: put, data }) }五、在 Vue 组件中使用封装完成后在 Vue 组件中调用请求会非常简洁且错误处理已统一封装无需重复编写。Vue3 组合式 API 示例template div el-button clickgetUserInfo获取用户信息/el-button /div /template script setup import { getUserInfo } from /api/user import { ElMessage } from element-plus const getUserInfo async () { try { // 直接获取核心数据无需解析code/data const data await getUserInfo() console.log(用户信息, data) ElMessage.success(获取用户信息成功) } catch (error) { // 可选特殊场景下自定义错误处理通用错误已在拦截器处理 console.error(获取用户信息失败, error) } } /scriptVue2 选项式 API 示例template div el-button clickgetUserInfo获取用户信息/el-button /div /template script import { getUserInfo } from /api/user import { Message } from element-ui export default { methods: { async getUserInfo() { try { const data await getUserInfo() console.log(用户信息, data) Message.success(获取用户信息成功) } catch (error) { console.error(获取用户信息失败, error) } } } } /script六、进阶优化请求取消、重复请求拦截1. 取消重复请求避免短时间内重复发送相同请求如多次点击提交按钮// 在request.js中添加 const pendingRequests new Map() // 存储待处理的请求 // 生成请求唯一标识 const generateRequestKey (config) { return ${config.method}-${config.url}-${JSON.stringify(config.params || config.data)} } // 添加请求到待处理列表 const addPendingRequest (config) { const key generateRequestKey(config) config.cancelToken new axios.CancelToken((cancel) { if (!pendingRequests.has(key)) { pendingRequests.set(key, cancel) } }) } // 取消重复请求 const cancelPendingRequest (config) { const key generateRequestKey(config) if (pendingRequests.has(key)) { const cancel pendingRequests.get(key) cancel(重复请求已取消) pendingRequests.delete(key) } } // 在请求拦截器中添加 service.interceptors.request.use( (config) { // 取消重复请求 cancelPendingRequest(config) // 添加当前请求到待处理列表 addPendingRequest(config) // 原有逻辑... return config }, (error) { // 原有逻辑... } ) // 在响应拦截器中移除已完成的请求 service.interceptors.response.use( (response) { cancelPendingRequest(response.config) // 原有逻辑... }, (error) { cancelPendingRequest(error.config) // 原有逻辑... } )2. 自定义请求配置支持业务请求覆盖默认配置如超时时间、响应类型// 示例上传文件请求修改Content-Type export const uploadFile (data) { return request({ url: /upload, method: post, data, headers: { Content-Type: multipart/form-data }, timeout: 30000 // 上传文件超时时间延长至30秒 }) }七、总结通过以上封装我们实现了 Vue 与 Axios 的优雅集成核心优势如下代码复用统一的请求 / 响应拦截逻辑避免业务代码冗余易于维护按模块拆分请求配置集中管理修改更便捷用户体验统一的加载状态、错误提示提升交互一致性健壮性处理了 Token 过期、重复请求、网络异常等边界场景简洁易用业务代码只需关注核心逻辑无需重复解析响应、捕获错误。这套封装方案适配 Vue2 和 Vue3可根据项目实际需求如 UI 框架、状态管理工具灵活调整是 Vue 项目中网络请求层的通用最佳实践。