例子中使用到的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)),必須攜帶一些特殊的信息。