網絡模塊axios的簡單應用

1、axios的基本使用

例子中使用到的url僅做爲示例,不必定有效,想要復現代碼須要使用可以提供數據的有效服務器接口urlvue

1.1.什麼是axios

axios:ajax i/o system;是用於在Vue.js中發送網絡請求的第三方框架;node

可經過許多方式發送網絡請求好比:ios

  • 選擇一:傳統的Ajax,配置和調用方式十分混亂,不推薦;
  • 選擇二:jQuery-Ajax,基於jQuery框架,不適合在Vue.js中使用;
  • 選擇三:官方在Vue1.x時推出的Vue-resource,因爲官方再也不維護,不推薦;
  • 最佳選擇:Vue.js做者尤雨溪推薦的axios,具備很是多的優勢,使用起來也十分方便。

1.2.安裝axios

想要使用axios首先要在node中安裝axios,因爲運行時依賴axios,因此採用‘--save’的安裝方式。ajax

npm install axios --save

1.3.axios的基本使用

//首先要引入
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);
  
})

1.4.axios發送併發請求

如下爲使用全局的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);
}))

1.5.建立axios實例請求數據

經過建立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
})

2、axios的應用

2.1.不規範的寫法

在組件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的依賴使用其餘框架就會變得十分複雜。因此這種請求數據的方式雖可行,可是很是不規範。不符合"高內聚,低耦合"的程序設計思想。服務器

2.2.axios的規範用法

單獨封裝一個axios組件進行數據請求(模塊化思想)。如圖,這樣即便第三方框架axios更改了,只須要修改封裝的組件x便可。因此,當咱們使用第三方框架的時候,最好採用這種方式,減少對第三方框架的依賴,便於維護。網絡

image-20200225121018327

首先在,項目目錄的src(源碼)文件夾下新建network文件夾,再在裏面新建request.js文件,專門用於放置axios數據請求組件:併發

image-20200225131402281

如下示例爲,在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()函數而已,十分利於維護。


3、axios攔截器

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)
})

請求攔截:

image-20200225150713098

image-20200225150640465

能夠看到當成功發出請求時,在request.js中的第88行打印了請求攔截的信息就是出傳入的config相關配置。當發送請求失敗時,由use()的第二個參數(函數)打印失敗信息。

響應攔截:

image-20200225154655619

image-20200225154757043

當服務器響應失敗時,由use()的第二個參數(函數)打印失敗信息。

爲何須要請求攔截?/請求攔截的做用

  • 當config中的一些信息不符合服務器的要求時。好比修改headers信息,除了能夠在建立axios實例時修改時,還能夠攔截以後進行修改。

  • 當每次發送網絡請求時,都但願在界面中顯示一個請求的圖標。就能夠在攔截後經過show()顯示出來,請求成功後,再在相應攔截中進行隱藏。
  • 某些網絡請求(好比登陸(token)),必須攜帶一些特殊的信息。

相關文章
相關標籤/搜索