例子中使用到的url仅做为示例,不必定有效,想要复现代码须要使用可以提供数据的有效服务器接口urlvue
axios:ajax i/o system;是用于在Vue.js中发送网络请求的第三方框架;node
可经过许多方式发送网络请求好比:ios
想要使用axios首先要在node中安装axios,因为运行时依赖axios,因此采用‘--save’的安装方式。ajax
npm install axios --save
//首先要引入 import axios from 'axios' //1.最基本的使用方式,method表示请求数据的方法,res为请求到的数据,可在then()中处理。(url仅为示例,表示的服务器接口并不必定存在) axios({ url: 'http://123.207.32.32:8000/home/multidata', method: 'get' }).then(res => { console.log(res); }) //2.进行参数拼接 axios({ url: 'http://123.207.32.32:8000/home/data', // 专门针对get请求的参数拼接 params: { type: 'pop', page: 1 } }).then(res => { console.log(res); })
如下为使用全局的axios和对应的配置进行网络请求,其中的url都要拼接上baseURL。这种方式只能向固定的服务器接口地址'http://123.207.32.32:8000' 请求数据,不能知足向不一样的分布式服务器请求数据的需求。npm
//定义全局的baseURL和请求时间timeout axios.defaults.baseURL = 'http://123.207.32.32:8000' axios.defaults.timeout = 5000 //使用axios.all()进行并发的数据请求,一样使用then()处理请求到的数据 axios.all([axios({ url: '/home/multidata' }), axios({ url: '/home/data', params: { type: 'sell', page: 5 } })]) .then(axios.spread((res1, res2) => { console.log(res1); console.log(res2); }))
经过建立axios实例,每个被建立的实例都有各自的配置,能够向不一样ip地址的服务器请求数据,彼此互不干扰。axios
//建立第一个axios实例:instance1 const instance1 = axios.create({ baseURL: 'http://123.207.32.32:8000', timeout: 5000 }) //实例instance1可单独的向服务器请求数据并进行处理 instance1({ url: '/home/multidata' }).then(res => { console.log(res); }) //也能够采用拼接参数的方式请求数据,实例instance1拥有本身的配置 instance1({ url: '/home/data', params: { type: 'pop', page: 1 } }).then(res => { console.log(res); }) // 若是有其余请求能够再建立一个axios的实例:instance2,这样就能够向其余ip地址的服务器接口请求数据了 const instance2 = axios.create({ baseURL: 'http://222.111.33.33:8000', timeout: 10000, // headers: { }//还能够根据须要配置对应的headers })
在组件App.vue中按以下方式请求数据,并进行展现:api
<template> <div id="app"> <!-- 打印请求到的数据 --> <div>{{result}}</div> </div> </template> <script> // 引入axios import axios from 'axios' export default { name: 'App', components: { }, data(){ return { // 对请求来的数据进行处理(这里省略) result:'' } }, //生命周期函数created():在Vue实例建立的时候就调用。在这里实现,Vue实例一建立便发送数据请求 created(){ axios({ url: 'http://123.207.32.32.:8000/api/home/multidate' }).then(res => { console.log(res); // 将请求到的数据res存储到data中 this.result = res; }) } } </script> <style> </style>
虽然这种方法也能够正常请求到数据,可是,若是每个组件都使用这种方式请求数据,就会对第三方框架axios产生过分的依赖。一旦axios框架再也不维护或出现重大bug再也不修复,想要在原有项目中去除对第三方框架axios的依赖使用其余框架就会变得十分复杂。因此这种请求数据的方式虽可行,可是很是不规范。不符合"高内聚,低耦合"的程序设计思想。服务器
单独封装一个axios组件进行数据请求(模块化思想)。如图,这样即便第三方框架axios更改了,只须要修改封装的组件x便可。因此,当咱们使用第三方框架的时候,最好采用这种方式,减少对第三方框架的依赖,便于维护。网络
首先在,项目目录的src(源码)文件夹下新建network文件夹,再在里面新建request.js文件,专门用于放置axios数据请求组件:并发
如下示例为,在request.js文件中封装axios数据请求模块,在main.js中进行数据请求。
在request.js中:
//导入第三方框架 import axios from 'axios' //1.建立axios的实例(不要使用全局的方式)并进行相应配置 /* 为了考虑扩展性,不要用export default 直接导出axios对象。而是一函数形式导出,函数里面可有多个axios实例 传入三个参数:其中success和failure分别是表示请求成功和失败后的处理函数,负责把请求到的数据经过回调传出去 */ export function request(config, success, failure) { //该函数的基本配置 const instance = axios.create({ baseURL: 'http://123.207.32.32:8000', timeout: 5000 }) //2.发送真正的网络请求(在该函数的相同配置下可建立不一样的实例); /* 这里axios实例instance的参数config是在request函数基本配置基础上的配置:传入config中的url: '/home',那么加上request函数的基本配置,最后请求数据的url:'http://123.207.32.32:8000/home';至关于request函数肯定请求的服务器地址,request函数里的axios实例请求同一服务器上的其余接口(分页)数据。 */ instance(config) .then(res => { // 经过回调传入的success函数的方式把请求到的数据传出去 success(res) }) .catch(err => { // 同上 failure(err) }) } /* 可传出包含多个实例的多个函数 export function instance2() { }
在main.js文件中请求数据:
//导入第三方框架 import axios from 'axios' // 引入request函数. import { request } from "./network/request"; //调用request函数,传入三个参数 request( // 参数1:config { url: '/home/multidata' }, // 参数2:success函数 /* 补充:如何实现回调? 1.把success函数看成参数传入request函数; 2.request函数调用传进来的success函数,并传入请求到的数据:success(res); 3.success(res)至关于函数调用,回到了这里调用success函数,并成功地把res传了过来. */ res => { console.log(res);//处理代码 }, // 参数3:failure函数 err => { console.log(err); } )
只给request函数传入一个参数config:
在request.js中:
// 导入axios框架 import axios from 'axios' //要求传入的config中包含success和failure两个函数 export function request(config) { const instance = axios.create({ baseURL: 'http://123.207.32.32:8000', timeout: 5000 }) //2.发送真正的网络请求,config.baseConfig负责传入各axios实例的配置 instance(config.baseConfig) .then(res => { // 经过config调用success函数 config.success(res) }) .catch(err => { config.failure(err) }) }
在main.js文件中请求数据:
// 引入request函数. import { request } from "./network/request"; //仅传入一个参数:config对象 request ({ baseConfig: { // 基本配置 }, success: function(res){ //处理代码 }, failure: function (err){ //处理代码 } })
上面的两种方式都是采用回调函数的方式,不够优雅。更加优雅的方式是采用ES6的Promise实现:
在request.js中:
// 导入axios框架 import axios from 'axios' export function request(config) { //在函数中返回一个新建的Promise对象 return new Promise((resolve, reject) => { //1.发送真正的网络请求 const instance = axios.create({ baseURL: 'http://123.207.32.32:8000', timeout: 5000 }) //2.发送真正的网络请求,config.baseConfig负责传入基本配置 instance(config) .then(res => { //经过Promise对象的resolve和reject函数把请求到的数据传出去 resolve(res) }) .catch(err => { reject(err) }) }) }
在main.js文件中请求数据:
// 引入request函数. import { request } from "./network/request"; //注意request函数返回了一个Promise对象,因此能够直接.then()进行处理 request({ url: '/home/multidata', }).then(res => { console.log(res) }).catch(err => { console.log(err) })
觉得就只有上面三种封装方法?还有对优雅的封装方式呢:
在request.js中:
export function request(config) { //1.建立axios实例 const instance = axios.create({ baseURL: 'http://123.207.32.32:8000', timeout: 5000 }) //2.发送真正的网络请求 // 实际上instance(config)返回的便是一个Promise,没必要像方式三同样在函数中封装一层Promise并返回出去 return instance(config) }
在main.js文件中请求数据:
// 引入request函数. import { request } from "./network/request"; request({ url: '/home/multidata', }).then(res => { console.log(res) }).catch(err => { console.log(err) })
总结:封装的方式推荐使用方式四,最灵活也最简洁。封装完毕以后,想要发送网络请求只须要引入并调用request()函数就好了。这样,即便axios框架不维护了,也只是须要更改request()函数而已,十分利于维护。
axios提供了拦截器,用于在每次发送完请求或者获得响应后,进行对应的处理。
拦截器一共提供了四种拦截:
在上面封装好的request.js基础上添加拦截器:
export function request(config) { //1.建立axios实例 const instance = axios.create({ baseURL: 'http://123.207.32.32:8000', timeout: 5000, // headers:{} }) /* 2.axios拦截器 axios.interceptors:全局拦截器 局部拦截器(仅拦截instance实例) use()的两个参数都为函数 */ /* 2.1.请求拦截: 成功发出请求时,使用use()第一个参数(函数)处理; 发出请求失败时,使用use()第而个参数(函数)处理 */ instance.interceptors.request.use( //拦截到的时config配置信息 config => { console.log(config);//打印拦截信息 /* 这里能够对拦截到的信息进行处理 */ //拦截完config以后必定要返回,否则请求就发不出去了 return config; }, err => { console.log(err); } ); /* 2.2.响应拦截: 响应成功,使用use()第一个参数(函数)处理; 响应失败,使用use()第而个参数(函数)处理 */ instance.interceptors.response.use( //拦截到的是服务器返回的数据res res => { console.log(res); // 一样处理完后必定要返回被拦截的结果res,这里只返回res.data便可,由于服务器的响应通常是数据 return res.data; }, err => { console.log(err); } ) //3.发送真正的网络请求 return instance(config) }
在main.js中调用request函数发送网络请求:
// 引入request函数. import { request } from "./network/request"; request({ url: '/home/multidata', }).then(res => { console.log(res) }).catch(err => { console.log(err) })
请求拦截:
能够看到当成功发出请求时,在request.js中的第88行打印了请求拦截的信息就是出传入的config相关配置。当发送请求失败时,由use()的第二个参数(函数)打印失败信息。
响应拦截:
当服务器响应失败时,由use()的第二个参数(函数)打印失败信息。
为何须要请求拦截?/请求拦截的做用
当config中的一些信息不符合服务器的要求时。好比修改headers信息,除了能够在建立axios实例时修改时,还能够拦截以后进行修改。
某些网络请求(好比登陆(token)),必须携带一些特殊的信息。