Vue-Axios
构建优雅的异步请求
网络请求模块的选择axios
选择什么网络模块?
vue
中发送网络请求有非常多的方式,那么在开发中如何选择呢?
选择一、传统的Ajax
是基于XMLHttpRequest(XHR)
为什么不用Ajax
呢?
一、配置和调用方式非常混乱。
二、编码起来看起来就非常蛋疼。
三、真实的开发中,很少直接使用JQuery
的Ajax
进行网络请求。
选择二、经常会使用JQuery-Ajax,相对已传统的Ajax非常好用。
为什么也不选着它呢?
一、在
vue
的整个开发过程中都是不需要使用jquery
了。
二、意味着为了方便我们进行一个网络请求,特意引用一个JQery
合理吗?。
三、jQuery
代码1w+
。vue
的代码才1w+
。
四、完全没有必要为了网络请求就引用了这个重量级的框架。
选着三、官方vue1.x
推出了Vue-resource
,vue-resource
相对已jQuery
体积相对于JQuery
小了很多,另外Vue-resource
是官方推出的。
为什么又不选择它呢?
一、
vue2.0
推出后,Vue
作者就在gitHub
的Issues
中说明了,去掉vue-resource
,并且以后再也不会更新。
二、意味着vue-resource
不在支持新的版本时,也不会再继续更新和维护。
三、对以后的项目开发和维护都存在很大的隐患。
选择四、在说明了不继续更新和维护vue-resource
的同时,还推荐了一个框架axios
为什么用他呢?axions
有非常多的优点,并且用起来也非常的方便
jsonp
在前段开发中,常见的网络请求方式就是jsonp
,使用jsonp
最主要的原因往往是为了解决跨域访问的问题。
jsonp
的原理是什么呢?
jsonp
的核心在于通过script
标签的src
来帮助我们请求数据,原因是我们的项目部署在domain1.com
服务器上的时候,是不能直接访问domain2.com
服务器上的资料的, 这个时候,我们利用script
标签的src
帮助我们去服务器请求到数据,将数据当做一个javascript
函数来执行,并且执行的过程中传入我们需要的json
, 所以封装jsonp
的核心就在于监听window
上的jsonp
进行回调时的名称。
为什么选择axions
呢?
功能特点:
一、在浏览器中发送
XMLHttpRequest
请求 。
二、在node.js
中发送http
请求。
三、支持Promise API
。
四、拦截请求和响应 。
五、转换请求和响应数据。
axios
框架的安装和基本使用
axios
支持多种请求的方式:
axios(config)
这是 Axios 最通用的请求方法,它可以接受一个配置对象作为参数,该对象包含了请求的所有细节,如URL、HTTP
方法、请求头、数据等。这使得你可以发送任何类型的HTTP
请求,只需正确配置参数即可。
例:
axios({
method: 'get',
url: 'https://api.example.com/data',
headers: {'My-Custom-Header': 'foobar'}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
axios.request(config)
这实际上与axios(config)
是相同的方法,只是提供了另一种调用方式。它接收同样的配置对象参数。
axios.request({
method: 'post',
url: 'https://api.example.com/data',
data: {
key1: 'value1',
key2: 'value2'
}
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
axios.get(url[,config])
这是一个用于发送GET
请求的快捷方法,它接受请求的URL
作为第一个参数,可选的配置对象作为第二个参数。
axios.get('https://api.example.com/data')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
axios.delete(url[,config])
用于发送DELETE
请求的快捷方法,参数与axios.get
类似。
axios.delete('https://api.example.com/data/123')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
axios.head(url[,config])
用于发送HEAD
请求的快捷方法,参数与axios.get
类似。
axios.head('https://api.example.com/data')
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
axios.post(url[,data[,config]])
用于发送POST
请求的快捷方法,第一个参数是URL
,第二个参数是请求体数据,第三个参数是可选的配置对象。>
axios.post('https://api.example.com/data', {
key1: 'value1',
key2: 'value2'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
axios.put(url[,data[,config]])
用于发送PUT
请求的快捷方法,参数与axios.post
类似。
axios.put('https://api.example.com/data/123', {
key1: 'newvalue1',
key2: 'newvalue2'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
axios.patch(url[,data[,config]])
用于发送PATCH
请求的快捷方法,参数与axios.post
类似。
axios.patch('https://api.example.com/data/123', {
key1: 'patchedvalue1'
})
.then(function (response) {
console.log(response);
})
.catch(function (error) {
console.log(error);
});
安装axios依赖:
npm install axios --save
npm axions -v
模拟请求
模拟服务器请求的url:http://123.207.32.32:8000/home/multidata
简单例子:
import Vue from 'vue'
import App from './App'
import router from './router'
import axios from 'axios'
Vue.config.productionTip = false
/* eslint-disable no-new */
new Vue({
el: '#app',
router,
render: h => h(App)
})
axios({
url:"http://152.136.185.210:7878/api/hy66/home/data?type=pop&page=3",
method:"get"
}).then(res=>{
console.log(res)
})
其中params
属性可以在vue
系统内自行拼接,专门对get
请求进行拼接:
以上两种效果一致,返回结果:
axios发送并发请求
有时候,可能同时发送两个请求。
使用
axios.all
,可以放入多个请求的数组。
axios.all([])
返回结果是一个数组。
使用axios.spread
可将数组[res1,res2]
展开为res1,res2
。
实例代码:
//2.axios发送并发请求
axios.all([
axios({
url:"http://123.207.32.32:8000/home/multidata"
}),
axios({
url:"http://152.136.185.210:7878/api/hy66/home/data",
method:"get",
params:{
type:"pop",
page:1
}
})
]).then(axios.spread((res1,res2)=>{
console.log(res1);
console.log(res2);
}))
效果:
axios的配置信息相关
在上面例子中,我们的BaseURL
是固定的,事实上,在开发中,很可能很多参数都是固定的,这个时候我们可以进行一些抽取,也可以利用axiox
的全局配置。
这里可以进行axios
的属defaults
性进行全局设置:
axios
常见的配置选项
一、请求地址:
url:'/user'
。
二、请求类型:method:'get'
。
三、请求根路径:baseURL:"http://www.**.com"
。
四、请求前的数据处理:transformRequest[{function(data){}}]
。
五、请求后的数据处理:transformResponse:[function(data){}]
。
六、自定义的请求头:headers:{'x-Requested-With':XMLHttpRequest'}
。
七、URL查询对象:params:{id:12}
。
axios
的实例和模块封装
为什么要创建axios实例?
之所以创建axios
实例,是因为有的项目中,可能要访问多个服务地址,而这些服务请求和相应的结构也可能完全不同,那么你可以通过axios.create
创建不同的实例来处理,比如axios1
是用http
状态码确定是否正常,而axios2
是服务器自己定义的状态码,又或者他们请求头不同,支持的content-type
不同,那么可以为单独定义两个实例写拦截。
实例代码:
/4.创建对应的axios实例
const instancel_1 = axios.create({
baseURL:"http://152.136.185.210:7878/api/hy66",
timeout:5000
})
const instancel_2 = axios.create({
baseURL:"http://123.207.32.32:8000",
timeout:5000,
headers:{
}
})
instancel_1({
url:"/home/multidata"
}).then(res=>{
console.log(res);
})
instancel_1({
url:"/home/data",
params:{
type:"pop",
page:1
}
}).then(res=>{
console.log(res);
})
上面创建了两个实例:instancel_1
和instancel_2
实例,分别两个服务器的根目录。
axios的封装
api
统一管理,不管接口有多少,所有的接口都可以非常清晰,容易维护,通常情况下,项目越来越多越来越大,页面也会越来越多,如果页面非常少,直接使用axios
也没有什么大的影响,那页面如果很多的话,上百个接口,上百个页面,这时候如果后端改了接口,多加了一个参数啥的,那就只能逐个页面进行修改,过程繁琐,不易维护和迭代,这个时候我们就要统计的管理接口,需要修改某一个接口的时候直接在api
里修改对应的请求,就很方便。
封装方法一、新建一个network
文件夹,里面新建一个request.js
文件,代码如下:
import axios from "axios"
export function request(config,success,failure){
//1.创建axios的实例
const instance = axios.create({
baseURL:'http://152.136.185.210:7878/api/hy66',
timeout:5000
})
//发送真正的网络请求
instance(config)
.then(res=>{
success(res);
})
.catch(err=>{
failure(err);
})
}
上面代码通过回调函数进行封装,在main.js
里面写入调用代码:
//5.封装一个request模块
import {request} from './network/request';
request({
url:"/home/multidata"
},res=>{
console.log(res);
},err=>{
console.log(err);
})
封装方法二、通过第一个参数传入success
和failure
的封装方式
request.js
代码:
//方式二、
import axios from "axios"
export function request(config){
//1.创建axios的实例
const instance = axios.create({
baseURL:'http://152.136.185.210:7878/api/hy66',
timeout:5000
})
//发送真正的网络请求
instance(config.baseConfig)
.then(res=>{
config.success(res);
})
.catch(err=>{
config.failure(err);
})
}
main.js
调用request
封装的axios
代码:
request({
baseConfig:{
url:"/home/multidata"
},
success:function(res){
console.log(res);
},
failure:function(err){
console.log(err);
}
})
以上都不是最完美的封装,下面将达到最理想的封装~使用Promise
进行封装
requesi.js代码:
// import axios from "axios"
// export function request(config,success,failure){
// //1.创建axios的实例
// const instance = axios.create({
// baseURL:'http://152.136.185.210:7878/api/hy66',
// timeout:5000
// })
// //发送真正的网络请求
// instance(config)
// .then(res=>{
// success(res);
// })
// .catch(err=>{
// failure(err);
// })
// }
//方式二、
// import axios from "axios"
// export function request(config){
// //1.创建axios的实例
// const instance = axios.create({
// baseURL:'http://152.136.185.210:7878/api/hy66',
// timeout:5000
// })
// //发送真正的网络请求
// instance(config.baseConfig)
// .then(res=>{
// config.success(res);
// })
// .catch(err=>{
// config.failure(err);
// })
// }
import axios from "axios"
export function request(config){
return new Promise((resolve,reject)=>{
//1.创建axios的实例
const instance = axios.create({
baseURL:'http://152.136.185.210:7878/api/hy66',
timeout:5000
})
//发送真正的网络请求
instance(config)
.then(res=>{
resolve(res)
})
.catch(err=>{
reject(err)
})
})
}
main.js
调用代码:
request({
url:"/home/multidata"
}).then(res=>{
console.log(res);
}).catch(err=>{
console.log(err);
})
最终方案二、使用instance
,因为instance
使用的时候本身返回的就是Promise
//最终方案二
import axios from "axios"
export function request(config){
//1.创建axios的实例
const instance = axios.create({
baseURL:"http://152.136.185.210:7878/api/hy66",
timeout:5000
})
//发送真正的网络请求
return instance(config)
}
main调用代码:
//最终方案二、
request({
url:"/home/multidata"
}).then(res=>{
console.log(res);
}).catch(err=>{
console.log(err);
})
效果:
如果以后axios
不再维护的话,如下方法进行:
request.js
代码
//最终方案二,如果axios不进行维护了如下解决
//import axios from "axios"
import android from 'android'
export function request(config){
//创建android的实例
android代码
return new Promise(
讲android代码包装到promise里面
)
}
调用代码:
request({
url:"/home/multidata"
}).then(res=>{
console.log(res);
}).catch(err=>{
console.log(err);
})
完结~