使用场景
开发当中通常需要使用后端提供的API接口来获取数据或与服务器进行交互。为了更好地进行模块化开发,通常需要将请求的功能封装成一个模块方便使用。
文件目录(个人习惯)
一般都是设置一个 config.js / api.js / index.js (默认配置信息), 另外一个则是 ajax.js / request.js (封装请求函数)
操作
1. Axios的二次封装
1.1 基本配置参数
进行 axios 二次封装之前,在 request.js 首先使用 axios.create()创建一个实例,设置变量接收这个实例,接下来就可以配置其他信息,例如请求地址和请求超时时间.
let request = axios.create({
// 拦截不建议写死
BaseURL:" ", //发起请求时自动携带这个URL
timeout:5000
})
// 最后记得全局暴露
export default request
接下来将对 requests 进行设置拦截器
1.2 设置请求/响应拦截器
1.2.1 请求拦截器
作用: 在请求发送前进行一些请求配置,或者携带请求的公共参数(token…)、其他逻辑操作都可以(检验token,添加loading状态,取消请求…)
例如在每个请求头里加上token个人令牌:
requests.interceptors.request.use((config)=>{
//请求成功时执行
config.headers.token = XXX
},(err) => {
//请求失败时执行
//中断Promise链
return new Promise.reject(err)
}
})
1.2.2 响应拦截器
作用: 请求返回时先拦截下来,对返回的数据进行统一处理,统一处理错误信息,方便我们定位和解决问题。
requests.interceptors.response.use( res => {
//响应成功时执行
return res.data;
},err => {
//响应失败时执行
//中断Promise链
return new Promise
}
)
// 使用 axios 二次封装的代码
import request from './request'
2. Promise封装异步请求函数
我们都知道 Promise 可以更好地处理异步操作,其链式调用方式,可以避免地狱回调,而且支持并发请求,并且可以通过 .catch 在出错时可以捕获并进行相应的错误处理,从而提高代码可读性和可维护性 而开发中在请求过程中可能需要在每一种请求类型上有不同功能的需求
就拿 URL 参数拼接 来举例子:
其步骤:
拿到请求的地址参数(URL)将参数与请求地址进行拼接检验拼接是否出错,请求是否正常
代码如下:
export default function request(url,data={},method:'GET'){
return new Promise(function(resolve,reject){
let promise;
if(method = 'GET'){
let dataUrl = ' ';
// URL参数拼接操作
promise = axios.get(dataUrl)
}
if(method = 'POST'){
// POST请求操作
promise = axios.post(url,data)
}
// 检验 Promise 请求是否出错
promise.then(response => {
resolve(response.data)
})
promise.catch(err => {
reject(err)
})
})
}
ps: 这个过程如果使用二次封装 axios 在请求拦截器里面貌似也可以实现,通过 config.baseURL 与 存放在 store.state 的参数拼接模板字符串
但是这个过程比较麻烦,因为拦截器是对所有的请求都会拦截一次,无论是 GET、POST…请求都一样,如果我只是想在Get 请求实现,那在其他的请求类型里面来看就是多余的,这样增加了代码的冗余,耦合程度较高
当然想实现这种功能并不止这一种方法,axios 本身就可以接收一个对象作为形参,对象内的 params 可以自动将参数写在 URL 链接后面
axios({
method:'GET';
url:''
params:{
// 参数属性名和属性值
}
})
// 如下:
export const reqAddress = (a,b,c) => request({
url:'';
method='GET',
params:{
a,
b,
c
}
})
这种的话感觉就是无法灵活地决定参数的个数
2. 管理所有api请求函数
完成对 axios 的二次封装后,就可以对每一个模块中需要发送的请求配置进行编写,一般是放在 config.js / api.js / index.js , 通过全局暴露让项目内的所有地方都可以使用,这种管理每一项 api请求 的方法其优势在于提高代码的可读性和维护性,更有利于模块化开发的思想。 例如编写请求地址的函数:
// 例如请求地址的函数
export const reqAddress = (data) => request()
// 例如请求天气的函数
export const reqWeather = (data) => request()
// 后面引用某一个时在文件编写
import {reqAddress,reqWeather } from './config'
最后总结(优势)
1. 代码复用
封装成一个函数,可以在多个地方使用,避免重复编写相同的代码
2. 代码实用性
使用者无需关心内部如何具体实现,只知道如何使用接口就行
3. 统一管理
将所有请求都集中到一个模块,方便统一管理和维护
4. 方便调试
方便地进行单元调试,逐一找出存在问题的地方
以上内容为本人在学习中总结的知识,如有错误欢迎指正,谢谢观看