從0到1使用VUE-CLI3開發實戰(四): Axios封裝

周小肆發表於2019-02-16

從0到1使用VUE-CLI3開發實戰(四): Axios封裝

有很多同學看了本系列的前幾篇之後建議我暫時先不用TS,於是小肆之後將把TS換成JS繼續下面的文章。
今天給大家帶來專案中非常重要的一環,配置Axios,一起來看看吧。

axios 簡介

首先要明白的是axios是什麼:axios是基於promise(諾言)用於瀏覽器和node.js是http客戶端。

axios的作用是什麼呢:axios主要是用於向後臺發起請求的,還有在請求中做更多是可控功能。

  • 從瀏覽器中建立 XMLHttpRequest
  • 從 node.js 發出 http 請求
  • 支援 Promise API
  • 攔截請求和響應
  • 轉換請求和響應資料
  • 取消請求
  • 自動轉換JSON資料
  • 客戶端支援防止 CSRF/XSRF

專案配置

首先當然還是要安裝啦:
npm install axios

之後我們新建一個api資料夾用來放介面和axios的配置。
先給大家看看我配置好之後的資料夾目錄結構:

可以說這次配置是我劃分的比較詳細的配置方法了,具體每個檔案都分別做什麼用,我們現在來看看吧。

axios.js

這個檔案主要建立axios例項並對攔截器進行配置,不理解攔截器的同學可以看看下圖:

import axios from `axios`

// 建立 axios 例項
let service = axios.create({
  // headers: {`Content-Type`: `application/json`},
  timeout: 60000
})

// 設定 post、put 預設 Content-Type
service.defaults.headers.post[`Content-Type`] = `application/json`
service.defaults.headers.put[`Content-Type`] = `application/json`

// 新增請求攔截器
service.interceptors.request.use(
  (config) => {
    if (config.method === `post` || config.method === `put`) {
      // post、put 提交時,將物件轉換為string, 為處理Java後臺解析問題
      config.data = JSON.stringify(config.data)
    }
    // 請求傳送前進行處理
    return config
  },
  (error) => {
    // 請求錯誤處理
    return Promise.reject(error)
  }
)

// 新增響應攔截器
service.interceptors.response.use(
  (response) => {
    let { data } = response
    return data
  },
  (error) => {
    let info = {},
      { status, statusText, data } = error.response

    if (!error.response) {
      info = {
        code: 5000,
        msg: `Network Error`
      }
    } else {
      // 此處整理錯誤資訊格式
      info = {
        code: status,
        data: data,
        msg: statusText
      }
    }
  }
)

/**
 * 建立統一封裝過的 axios 例項
 * @return {AxiosInstance}
 */
export default function() {
  return service
}
index.js

index.js檔案主要封裝我們幾個常用的方法,get、post、put、delete

import axios from `./axios`

let instance = axios()

export default {
  get(url, params, headers) {
    let options = {}

    if (params) {
      options.params = params
    }
    if (headers) {
      options.headers = headers
    }
    return instance.get(url, options)
  },
  post(url, params, headers, data) {
    let options = {}

    if (params) {
      options.params = params
    }
    if (headers) {
      options.headers = headers
    }
    return instance.post(url, data, options)
  },
  put(url, params, headers) {
    let options = {}

    if (headers) {
      options.headers = headers
    }
    return instance.put(url, params, options)
  },
  delete(url, params, headers) {
    let options = {}

    if (params) {
      options.params = params
    }
    if (headers) {
      options.headers = headers
    }
    return instance.delete(url, options)
  }
}
install.js

install.js檔案可以把我們所有的api介面安裝到全域性,之後我們在main.js檔案中匯入就可以了。

import apiList from `./apiList`

const install = function(Vue) {
  if (install.installed) {
    return
  
  install.installed = true
  Object.defineProperties(Vue.prototype, {
    $api: {
      get() {
        return apiList
      }
    }
  })
}

export default {
  install
}
main.js中新增:
import api from `./api/install`
Vue.use(api)
apiList.js

把我們所有的api資料夾匯入到這一個檔案中來。

import matches from `./matches`
import user from `./user`

export default {
  matches,
  user
}
baseUrl.js

根據不同的環境設定不同的baseUrl,在配置這個檔案前,我們先需要做如下幾件事:
1.根目錄新建.env.dev檔案並在檔案內寫入NODE_ENV = `dev`
2.在package.json檔案內新增:

 "build:dev": "vue-cli-service build --mode dev",
 "build:pre": "vue-cli-service build --mode pre",

以下是baseUrl.js的程式碼:

let baseUrl = `/api` // 本地代理

switch (process.env.NODE_ENV) {
  case `dev`:
    baseUrl = `http://testserver.feleti.cn/` // 測試環境url
    break
  case `pre`:
    baseUrl = `https://pre-server.feleti.cn` // 預上線環境url
    break
  case `production`:
    baseUrl = `https://api.feleti.cn` // 生產環境url
    break
}

export default baseUrl
matches、user

這兩個資料夾都是根據api型別進行區分的,在專案以後也建議大家根據api型別劃分出不同的檔案存放,在小專案中這樣做可能顯得很麻煩,但如果專案比較大,這樣做的優勢就體現出來了。

我們就只看看matches資料夾下的內容:

urls.js

把一個型別下的所有url介面放入這一個檔案,我只放了一個暫時,可以繼續新增。

import baseUrl from `../baseUrl`
export default {
  matches: baseUrl + `/matches`
}
index.js

有些介面需要在header中新增token或是其他,可以按如下配置。

import api from `../index`
import urls from `./urls`

const header = {}

export default {
  matches(params) {
    // return出去了一個promise
    return api.get(urls.matches, params, header)
  }
}

配置完上述全部檔案就算是大功告成了,下面我們看看如何使用吧。

元件中呼叫

created() {
    this.matches()
  },
  methods: {
    async matches() {
      // 這裡用try catch包裹,請求失敗的時候就執行catch裡的
      try {
        //定義引數物件
        let params = {
          type: `zc`
        }
        let res = await this.$api.matches.matches(params)

        console.log(`​getMatches -> res`, res)
      } catch (e) {
        console.log(`​catch -> e`, e)
      }
    }
  }

之後我們就可以在控制檯看到我們呼叫成功的輸出日誌啦:

小結

在實際工作中,我們儘量要把專案做的細緻一些,尤其是專案開始之前的配置,今天所涉及到的很多檔案在之後的配置中還會有進步的更改,比如配置使用者相關的介面、配置全域性loading等,大家只要能把今天的內容完全理解,之後再配置這裡就很容易啦。

前置閱讀:

  1. 用vue-cli3從0到1做一個完整功能手機站(一)
  2. 從0到1開發實戰手機站(二):Git提交規範配置
  3. 從0到1使用VUE-CLI3開發實戰(三): ES6知識儲備

相關文章