axios的使用与封装
一、发送get请求
axios({
url:'***',
method:'get' //该句可省略,默认是get请求
}).then(data => {
console.log(data);
})
axios.get(url).then()
//get请求附带参数
axios({
url:'url1',
params:{
type:'',
page:''
}
}).then()
二、发送并发请求
不使用axios的话,发送并发请求有以下方法:
(1)通过ajax
let isResult1 = false,isResult2 = false;
function handleResult(){
if(isResult1 && isResult2){
//...
}
} //处理并发请求的函数
$.ajax({
url:'',
success(){
isResult1 = true;
handleResult();
}
})
$.ajax({
url:'',
success(){
isResult2 = true;
handleResult();
}
})
(2)通过Promise
new Promise.all([
new Promise((resolve,reject) => {
$.ajax({
url:'',
success:function(data){
resolve(data)
}
})
}),
new Promise((resolve,reject) => {
$.ajax({
url:'',
success:function(data){
resolve(data)
}
})
})
]).then(results => {
//results[0] 第一个请求返回的结果
//results[1] 第二个请求返回的结果
})
(3)通过axios
axios.all([axios(),axios()]).then(results => {}) //通过results[0],results[1]来访问结果
axios.all([axios(),axios()]).then(axios.spread(res1,res2) => {}) //直接访问结果
三、全局配置
axios.defaults.baseURL = ''
axios.defaults.timeout = 5000
axios.defaults.headers.post['Content-Type'] = ''
......
四、创建axios的实例
在项目中我们有时不会所有内容都部署在同一个服务器,或者说,我们在请求不同的数据时,希望的timeout等配置不同,这时,唯一的全局配置就会发生冲突,这时需要创建axios的实例,针对不同的需求使用不同的实例。
const instance1 = axios.create({
baseURL:'',
timeout:5000
})
instance1({
url:''
}).then()
五、在vue项目中使用axios
这里需要提出一个警告,设想我们在vue项目中使用axios时,我们计划在组件初始化时访问并获得数据,然后进行一个展示,那么,代码就可以写成下面这样:
<template>
<div>{{data}}</div>
</template>
export default {
name: "App",
data(){
return{
data:''
}
}
created(){
axios({
url:''
}).then(res => {
//处理加工
this.data = res;
})
}
}
这样写貌似没什么问题,但如果我们对项目中每一个需要请求网络数据的文件都采用这种方式,那么一旦将来的某一天该网络请求模块停止维护了,或者出现了严重的bug需要去更换新的网络请求模块时,那么到时我们就需要对每一个文件进行更改,那将是非常大的工作量。
因此,一旦我们在项目中需要用到第三方的工具,尽量要先把它进行一次封装之后再去使用。
这样,我们所有的文件都是面向我们的封装好的网络请求模块进行开发,就算之后我们需要更换其它的网络请求模块,我们也只需要更改这个封装文件就可以了。
我们新建一个request.js文件,作为我们的封装文件。
//request.js
import axios from 'axios'
export function request(config){
//1.创建axios的实例
const instance1 = axios.create({
baseURL:'',
timeout:5000,
//...
})
//2.发送网络请求
instance1.config(config.base)
.then(res => {
config.success(res);
})
.catch(err => {
config.failure(err);
})
}
//使用request
request({
base:'',
success:function(res){},
failure:{err}
})
改进:通过Promise实现链式调用:
import axios from 'axios'
export function request(config){
return Promise((resolve,reject) => {
const instace = axios.create({
baseURL:'',
timeout:5000,
//...
})
instance(config)
.then(res => {
resolve(res);
})
.catch(err => {
reject(err);
})
})
}
request({
url:''
}).then(res => {})
.catch(err => {})
另外,由于axios本身返回的就是Promise对象,因此代码可以进一步简化:
export function request(config){
const instace = axios.create({
baseURL:'',
timeout:5000,
//...
})
return instance(config)
}
这样,就算以后我们使用其它网络请求模块,只需要把request.js中相关axios的代码替换掉,然后返回一个Promise即可。
但是仅仅是这样还不太好,比如现在项目中有几个页面,分别是 home,cart,profile,每个页面去请求网络数据时,都是面向request.js,并且使用url的方式来获得数据,这样容易造成管理混乱,更好的方法是再做一层封装,在home,cart,profile与request.js之间再封装一个函数层。
比如以home页面为例,我可以创建一个home.js:
import {request} from "./request";
export function getHomeMultidata() {
return request({
url:'/home/multidata'
})
}
export function getHomecelldata() {
return request({
url:'/home/celldata'
})
}
export function getHomescolldata() {
return request({
url:'/home/scolldata'
})
}
//......
这样做的好处是,我在进行home页面的开发时,只需要考虑我需要什么数据,调用什么函数就行,不需要去考虑url,管理也更加方便,使代码耦合度更低。
六、拦截器
拦截器可以在我们每次发送请求后或者得到响应后拦截并进行相应的处理。
我们可以进行四种拦截:请求成功,请求失败,响应成功,响应失败。
instance.interceptors.request.use(
config => { //发送成功,获取发送请求的config配置对象
//处理代码,我们拦截请求后可能会去做下面一些事情:
//(1)config中一些配置不符合服务器要求,需要替换
//(2)每次发送网络请求时,希望在用户界面展示一个等待动画
//(3)某些网络请求(比如登陆需要token),必须携带特殊信息
return config //返回config,如果不返回,网络请求就无法发出
},
err => { //发送失败
}
)
instance.interceptors.response.use(
res => { //响应成功,获取响应结果
//处理代码
return res.data
},
err => { //响应失败
}
)
上一篇: CSS3 渐变
下一篇: C++程序的耦合性设计