vue + vite + js 项目中 axios的二次封装

大概算是学习记录吧。

目录

1. 前言

1.1 axios出现的原因

1.1.1 ajax(asynchronous JavaScript and XML)

1.1.2 jQuery-ajax

1.1.3 axios

1.2 axios是什么?

1.3 axios二次封装的目的及应用场景

2. 二次封装全过程

2.1 安装axios

2.2 添加文件结构

 2.3 封装axios,进行初始配置

2.3.1 请求拦截器

2.3.2 响应拦截器

2.4 封装各类请求

2.5 API统一管理

2.6 在组件中使用api

3. 心得


1. 前言

1.1 axios出现的原因

很久以前,当浏览器页面向服务器请求数据时,整个页面都会进行刷新,这会造成网络资源的占用,为了提高数据请求效率,异步网络请求ajax出现,它可以在页面无刷新的情况下请求数据。jQuery封装的ajax。原生的XHR(XMLHttpRequest),以及axios都可以实现异步网络请求。

1.1.1 ajax(asynchronous JavaScript and XML)

传统的ajax请求是基于XHR对象的,可以直接使用,但是其配置和调用方式十分混乱,所以在真实开发中很少使用,因此在MVC(Model模型-View视图-Controller控制器)框架中,取而代之使用jQuery-ajax实现前后端数据交互。而现在使用更多的则是fetch请求。

1.1.2 jQuery-ajax

jQuery-ajax底层原理也是对传统的ajax,XHR对象进行封装,但是在前端框架MVVC时代,如果在继续用ajax就还需要单独引入jquery,代码量巨大,得不偿失。因此针对于框架的网络请求就出现了。

1.1.3 axios

尤雨溪本人亲自推荐。相较XHR——简单易用,相较jQuery——尺寸小且提供了易于扩展的接口,是专注于网络请求的库。

1.2 axios是什么?

axios是一个基于promise的http库,可以用在浏览器和node.js中。

特点:

①支持从浏览器中创建XHR

②支持从node.js创建http请求

③可以调用promise的api

④能拦截请求和响应

⑤能转换请求数据和响应数据

1.3 axios二次封装的目的及应用场景

目的:对api进行统一管理,易于项目的维护和迭代,接口再多也不怕不怕啦。

(当没有二次封装时,若后端改了接口参数,就必须找到使用该接口的页面进行修改,非常繁琐)

业务场景:

①全局请求配置

②get/post/put/delete等请求的promise封装

③全局请求状态管理,供加载动画等使用

④请求携带token,权限错误统一管理

⑤路由跳转取消当前页面请求

⑥二次封装请求拦截器和响应拦截器

⑦多环境:开发、测试、生产

⑧统一错误处理:401、404、500等

2. 二次封装全过程

2.1 安装axios

npm i axios

2.2 添加文件结构

下图结构参考开源项目vben-admin。

在项目src文件夹下的util文件夹中添加一个http文件夹(也可以不放在util文件夹中),存放关于axios请求的相关文件,然后在http的axios文件夹中新建index.js文件(直接放在http文件夹下也可),用于封装axios。最后在src文件夹下新建api文件夹用于集中管理接口。

 2.3 封装axios,进行初始配置

在index.js文件中使用axios的create方法创建axios实例,并传入配置,同时设置请求拦截器和响应拦截器。(注:也有很多人的思路是封装一个函数,在函数内创建实例,然后在需要发送请求的位置调用这个函数,意味着每发送一个请求,都会创建一个新的axios实例,vben-admin就是这样做的)

如果后端服务有统一的网关入,那么在此仅创建一个实例就可以,但是如果后端接口地址有多个(www.test1.com、www.test2.com),并且一些默认配置还不同,如超时时长不同(1000ms、2000ms),此时就可以创建多个实例,用不同的实例去请求不同的接口,配置相关信息。

以下代码只创建了一个实例:

其中,axios的常见配置选项如下:

url:请求地址(必写)

method:请求方法,默认为get

baseURL:baseURL会添加到url前(url是绝对地址除外)

headers:自定义请求头信息

params:查询参数。只有get请求的params位于url后,其他请求的params都在请求体中。

data:请求体中的数据。此选项只适用于以下请求方式:put/post/patch。

timeout:请求超时时间。

withCredentials:设置是否允许携带cookie等凭证信息。

transformRequest:请求数据的转换函数。此选项只适用于以下几种请求方式——put/post/patch。

transformResponse:响应数据的转换函数。

validateStatus:判断请求状态是否成功的函数,可以自定义规则。

onUploadProgress:上传进度事件

onDownloadProgress:下载进度事件

maxContentLength:响应数据的最大长度

maxRedirects:重定向的最大次数

cancelToken:请求取消的令牌

2.3.1 请求拦截器

作用:在发送请求前进行一些操作。

原理:axios是对ajax的封装,它暴露出来的拦截器其实是写了一个方法,将ajax放在这个方法里卖弄,在执行的时候,先将请求时要添加给请求头的数据(如token等)都赋值给一个变量,然后统一传给ajax,然后才执行ajax。也就是说,请求拦截器就是将添加数据的过程抽离出来,并在发送ajax请求前执行。

使用场景:给所有的axios请求设置请求头(否则需要手动给每一个axios设置)、统一添加cookie/token、请求体加验证....

2.3.2 响应拦截器

作用:在接受到响应后执行一些操作。

原理:当请求结果返回后,先不直接导出,而是先对响应码等信息进行操作,处理好之后再到处给页面。也就是将处理对象响应码的过程抽离出来,构成所谓的响应拦截器。

使用场景:响应数据的统一处理,常用来对请求错误进行统一处理。

2.4 封装各类请求

有了axios实例和响应的配置,接下来就在常用的GET、POST等请求上应用上面的配置,封装请求方法的目的是为了使用起来更方便。

这里是否要对GET、POST等请求再封装一层promise?我看网上大家的意见都不太统一,但更多人觉得多封装一层是多余的,因为axios返回的就是promise对象

如果再套一层promise的话,return的时候直接new Promise,代码如下:

如果不套promise,代码如下:

我在编写这部分代码的时候好几次掉进了坑,得到的请求结果怎么都是undefined,仔细检查发现,主要需要注意的地方有两个:①直接返回axios请求时,如果使用了then和catch,那么需要在then或catch中返回处理后的结果,如上面我在then中将响应结果中的data属性进行了返回,如果没有return结果的话,那这个封装好的post函数在调用时,得到的结果就是undefined;②如果不是直接返回axios请求,而是在这个函数中使用axios发请求,然后返回结果,那么需要将这个函数修改为异步函数,否则返回的结果也会是undefined。

注:then到底需不需要用?我的理解:如果需要对响应数据进行处理的话,那么可以在then的回调函数中进行(但是对响应数据的处理在响应拦截器中也可以完成,两者的区别和执行顺序我现在还没弄清楚)。

补充:axios常用语法如下:

axios(config): 通用/最本质的发任意类型请求的方式
    axios(url[, config]): 可以只指定 url 发 get 请求
    axios.request(config): 等同于 axios(config)
    axios.get(url[, config]): 发 get 请求
    axios.delete(url[, config]): 发 delete 请求
    axios.post(url[, data, config]): 发 post 请求
    axios.put(url[, data, config]): 发 put 请求
    axios.defaults.xxx: 请求的默认全局配置
    axios.interceptors.request.use(): 添加请求拦截器
    axios.interceptors.response.use(): 添加响应拦截器
    axios.create([config]): 创建一个新的 axios(它没有下面的功能)
    axios.Cancel(): 用于创建取消请求的错误对象
    axios.CancelToken(): 用于创建取消请求的 token 对象
    axios.isCancel(): 是否是一个取消请求的错误
    axios.all(promises): 用于批量执行多个异步请求
    axios.spread(): 用来指定接收所有成功数据的回调函数的方法

补充:axios配置的优先级(由低到高):全局配置 < 实例配置 < 请求时配置

// 全局配置
axios.default.timeout = 3000

// 实例配置
let instance = axios.create()
instance.default.timeout = 2000

// axios请求时配置
instance.get('/url', {timeout:1000})

2.5 API统一管理

进入我们最初创建的api文件夹,新建user.js文件,在这里定义和用户相关的api,我们需要将刚刚封装好的请求列表导入然后使用,如以下是一个简单的用户登录api:

不同类型与功能的api放在不同的文件夹中,这样方便管理和后续查找维护。

2.6 在组件中使用api

以下是一个最简单的登录跳转(很多处理在这里还没完成,仅展示如何使用),就两步,导入+使用,我在这里是将用户对应的操作放到了store中,所以稍微绕一下: 

 

3. 心得

至此,axios的基础二次封装就结束了,更多复杂的功能就可以在这个基础上进行添加,如拦截器的设置、更多不同的请求方法的封装.......在整个梳理过程中我最大的感受是,涉及到很多基础的知识,如async/await与promise、js的事件循环机制、axios请求的各种配置等等,细节的地方稍不注意就会导致结果和预期不同,所以还是得反复练习把基础打牢。

后续想到什么再进行补充。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Vue 3,可以使用Vite构建工具来快速搭建项目。下面是一个简单的示例,演示如何使用ViteAxios进行二次封装。 首先,确保已经安装了ViteAxios。 1. 创建一个新的Vue项目: ```bash # 使用Vite创建新项目 npm init vite my-project cd my-project npm install ``` 2. 安装Axios: ```bash npm install axios ``` 3. 创建一个`api`文件夹,并在其创建一个`request.js`文件,用于封装Axios的请求逻辑: ```javascript import axios from 'axios' // 创建自定义Axios实例 const instance = axios.create({ baseURL: 'http://api.example.com', // 设置接口基本路径 timeout: 5000 // 设置请求超时时间 }) // 请求拦截器 instance.interceptors.request.use(config => { // 在发送请求之前做一些处理,例如添加认证信息等 return config }, error => { return Promise.reject(error) }) // 响应拦截器 instance.interceptors.response.use(response => { // 在接收到响应数据之前做一些处理,例如统一处理错误码等 return response.data }, error => { return Promise.reject(error) }) export default instance ``` 4. 在Vue组件使用封装好的Axios实例: ```javascript import request from '@/api/request' export default { methods: { fetchData() { request.get('/data') .then(response => { // 处理返回的数据 }) .catch(error => { // 处理请求错误 }) } } } ``` 使用以上方法,我们可以将Axios进行二次封装,在Vue项目更方便地使用。你还可以根据实际需求,进一步扩展封装的功能,例如处理全局错误、统一处理Loading状态等。 **

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值