Vue3-axios
Vue3-axios
一、前言
在Vue2.0时代开始,官方推荐使用axios
作为新一代的Ajax库。
axios
优点:在浏览器中发送XMLHttpRequest请求、在node中发送http请求、支持Promise API、拦截请求和相应、转换请求和响应数据等。
本文是基于Vue3
+axios1.4.x
+Vite4.x
环境描述。
二、axios安装
安装
$ yarn add axios
或
$ npm install axios
引入
import axios from "axios";
三、axios基本使用
axios请求方式
先来看看axios具体有哪些请求方式:
- axios(config)
- axios.request(config)
- axios.get(url[, config])
- axios.delete(url[, config])
- axios.head(url[, config])
- axios.post(url[, data[, config]])
- axios.put(url[, data[, config]])
- axios.patch(url[, data[, config]]) axios(config)请求方式: axios接收一个对象,在对象中使用
键值对
方式写入配置信息,get请求下,默认method可以不写。
axios({
url:'http://123.207.32.32:8000/home/multidata',
params:{
type:'pop',
page:1
}
}).then(res=>{
console.log(res);
}).catch(err=>{
console.log(err);
})
axios.request(config)请求方式: 与axios(config)写法一致,都是接收一个对象,在对象中使用键值对
方式配置信息。
axios.request({
url:'http://123.207.32.32:8000/home/multidata'
}).then(res=>{
console.log(res);
}).catch(err=>{
console.log(err);
})
axios.get(url[, config])请求方式 :限定method为get请求,网络请求中get请求是将参数拼接搭配url上发送的请求,在axios请求中则可以使用params
属性配置将传递的参数拼接到url上。params
属性是一个对象,其传递的参数使用键值对
形式书写
axios.get('http://123.207.32.32:8000/home/multidata',{
params:{
type:'pop',page:1
}
}).then(res=>{
console.log(res);
}).catch(err=>{
console.log(err);
})
axios配置
常见配置项
- 请求地址:
url: '/user'
- 请求类型:
method: 'get'
- 请根路径:
baseURL: 'http://www.mt.com/api'
- 请求前的数据处理:
transformRequest:[function(data){}]
- 请求后的数据处理:
transformResponse: [function(data){}]
- 自定义的请求头:
headers:{'x-Requested-With':'XMLHttpRequest'}
- URL查询对象:
params:{ id: 12 },
- 查询对象序列化函数:
paramsSerializer: function(params){ }
- request body:
data: { key: 'aa'}
- 超时设置:
timeout: 1000,
- 跨域是否带Token:
withCredentials: false
- 自定义请求处理:
adapter: function(resolve, reject, config){}
- 身份验证信息:
auth: { uname: '', pwd: '12'}
- 响应的数据格式json / blob /document /arraybuffer / text / stream:
responseType: 'json'
全局配置
第三方框架通过import axios from axios
引入axios属于全局的axios。使用default
关键字可以对axios进行一个配置。那么所有的axios请求都会携带default预先定义好的默认设置。对于公共的请求配置可以抽离出来,例如:请求超时时间、服务器地址、设置请求头等
语法格式:axios实例.default.配置项
参考代码:
// axios.defaults.配置项===》axios全局配置
axios.defaults.baseURL = 'http://123.207.32.32:8000'
axios.defaults.timeout = 5000
axios.defaults.headers['X-TOKEN'] = '123xxx'
axios.defaults.headers.post['Content-Type'] = 'application/x-www-form-urlencoded';
axios.defaults.responseType = 'blob'
axios('home/multidata',
{
params: {
type: 'pop',
page: 1
}
}
).then(res => {
console.log(res);
}).catch(err => {
console.log(err);
})
axios并发请求
有时候存在这样一种情况:同时发送多个请求,并且等到多个请求完成响应并拿到响应内容时候才会返回。这个时候就需要使用到并发请求。
axios.all()
本质上就是promise.all()。axios.all()
接收一个Array数组作为参数,每个参数成员就是要发送的axios请求体,axios.all()函数返回一个promise实例,通过.then方法接收响应的数据,并且响应的数据也包裹在一个Array数组中, 每个数组成员对应响应的请求结果。可以通过axios.spread()
函数将返回的数组[res1,res2]展开为,res1,res2。注意,并发请求如果有一个单独的请求失败,那么axios.all()函数整个请求就会报错,通过.catch()方法拿到报错信息。
axios.all([
axios.get('http://123.207.32.32:8000/home/multidata', { params: { type: 'pop', page: 1 } }),
axios({ url: 'http://123.207.32.32:8000/home/multidata', params: { type: 'pop', page: 1 } })
]).then(res => {
console.log(res) // 返回的是数组包裹的响应信息[res1,res2]
}).catch(err=>{
console.log(err)
})
axios.all([
axios.get('http://123.207.32.32:8000/home/multidata', { params: { type: 'pop', page: 1 } }),
axios({ url: 'http://123.207.32.32:8000/home/multidata', params: { type: 'pop', page: 1 } })
]).then(axios.spread((res1,res2) => { // 使用axios。spread展开数组
console.log(res1)
console.log(res2)
})).catch(err=>{
console.log(err)
})
创建axios实例
思考一下,我们通过
import axios from 'axios'
引入了全局的axios对象,为什么还要再单独创建axios实例呢?
在实际项目开发中,我们存在不同的请求默认配置可能不一样,例如,服务器地址、请求超时...默认配置不同,那么全局引进的axios再使用axios.default.配置项
设置全局的默认统一的配置无法解决这个问题。因此,我们使用axios.create()
函数创建新的axios实例,不同的axios实例可以设置不同的默认配置,各个axios实例之间的配置是互不影响的。
axios.create()
接收一个对象参数,使用键值对传入默认的配置,返回axios实例。
import axios from 'axios'
// axios实例1
const axiosInstance1 = axios.create({
baseURL:'http://123.207.32.32:8000',
timeout:5000
})
axiosInstance1({
url:'/home/multidata',
params:{
type:'pop',
page:3
}
}).then(res=>{
console.log(res)
}).catch(err=>{
console.log(err)
})
// axios实例2
const axiosInstance2 = axios.create({
baseURL:'http://192.168.5.110:9001',
timeout:5000
})
axiosInstance1({
url:'/home/multidata'',
params:{
type:'pop',
page:3
}
})
.then(res=>{
console.log(res)
}).catch(err=>{
console.log(err)
})
也可以对新创建的axios实例使用.default方法配置
import axios from 'axios'
// axios实例1
const axiosInstance1 = axios.create()
axiosInstance1.default.baseURL = 'http://123.207.32.32:8000'
axiosInstance1.default.timeout = 5000
axiosInstance1({
url:'/home/multidata',
params:{
type:'pop',
page:3
}
}).then(res=>{
console.log(res)
}).catch(err=>{
console.log(err)
})
axios拦截器
拦截器顾名思义即为拦截,对所有的请求和响应进行拦截。
方法:
axios.interceptor.request.use()
请求拦截器
axios.interceptor.response.use()
响应拦截器
两个拦截器使用方法一致,都接收两个参数:
- 参数1:拦截成功回调函数
- 参数2:拦截失败回调函数。 注意,无论请求还是响应拦截,拦截完了要return 返回拦截的请求体和响应体,不然就不会执行后边的请求和响应结果操作了。
可参axios照源码如下:
export interface AxiosInterceptorManager<V> {
use<T = V>(onFulfilled?: (value: V) => T | Promise<T>, onRejected?: (error: any) => any): number;
eject(id: number): void;
}
请求拦截器使用场景:
- 发送请求时添加‘正在加载中...’图标
- 某些请求必须用户登陆,判断是否有用户token,没有跳转到登陆页
- 对请求的参数进行序列化
axios.interceptor.request.use(res=>{
console.log('来到了request拦截的success中');
// 拦截完了要返回
return res
},err=>{
console.log('来到了request拦截的failure中');
})
响应拦截器使用场景:
- 返回响应的res.data数据结果
- 根据响应的status状态码,做出不同的操作。例如:如果status是401,响应拦截失败,那么通常是token失效,没有授权,要跳转至登陆页;status是200,响应拦截成功操作,返回res.data响应数据
axios.interceptor.response.use(res=>{
console.log('来到了response拦截的success中');
// 拦截完了要返回
return res.data
},err=>{
console.log('来到了response拦截的failure中');
})
四、axios在Vue项目中的封装
在项目中,我们通常会对请求进行二次封装,在项目中src/utils文件下新建request.js文件存放封装的请求,导入第三方请求库。那么为什么会二次封装请求呢?因为例如axios请求属于第三方库,如果后期作者不再维护axios库的时候,我们只需要修改request.js文件依赖的第三方框架部分,这样不会影响项目中其他需要发送请求的代码。
准备文件及文件夹
src\utils\http --------index.js #axios文件 --------reqIntercepter.js #请求拦截器 --------resIntercepter.js #响应拦截器
index.js
import axios from "axios";
import useReqIntercepter from './reqIntercepter'
import useResIntercepter from './resIntercepter'
const http = axios.create({
baseURL: import.meta.env.VITE_APP_BASE_URL,
timeout: 1000,
});
// 应用请求拦截器
useReqIntercepter(http)
// 应用响应拦截器
useResIntercepter(http)
export default http
将axios的实例http暴露出去,在其他接口文件中引入http即可使用。
reqIntercepter.js
export default function useReqIntercepter(axios) {
axios.interceptors.request.use(
function (config) {
// 在发送请求之前做些什么
return config;
},
function (error) {
// 对请求错误做些什么
return Promise.reject(error);
}
);
};
resIntercepter.js
export default function useResIntercepter(axios) {
axios.interceptors.response.use(
function (response) {
// 2xx 范围内的状态码都会触发该函数。
// 对响应数据做点什么
return response;
},
function (error) {
// 超出 2xx 范围的状态码都会触发该函数。
// 对响应错误做点什么
return Promise.reject(error);
}
);
};
转载自:https://juejin.cn/post/7243337546826039353