axios 二次封裝 api的統(tǒng)籌管理 配合async await實際項目中的運用

寫在前面


作者簡書地址
axios在實戰(zhàn)項目中的運用,所舉例項目是基于vue全家桶(vue-router+vuex+axios+element-ui)的后臺管理系統(tǒng),需要一些有vue項目開發(fā)經(jīng)驗的讀者閱讀。
由于vue-resource 作者宣布不再更新,促使我們使用第三方的request數(shù)據(jù)請求,一般我們的選擇有

  1. JQuery ajax
  • 本身是針對MVC的編程,不符合現(xiàn)在前端MVVM的浪潮
  • 基于原生的XHR開發(fā),XHR本身的架構(gòu)不清晰,已經(jīng)有了fetch的替代方案
  • JQuery整個項目太大,單純使用ajax卻要引入整個JQuery非常的不合理(采取個性化打包的方案又不能享受CDN服務(wù))
  1. fetch
  • 符合關(guān)注分離,沒有將輸入、輸出和用事件來跟蹤的狀態(tài)混雜在一個對象里
    更好更方便的寫法
  • 更加底層,提供的API豐富(request, response)
  • 脫離了XHR,是ES規(guī)范里新的實現(xiàn)方式
    1)fetchtch只對網(wǎng)絡(luò)請求報錯,對400,500都當做成功的請求,需要封裝去處理
    2)fetch默認不會帶cookie,需要添加配置項
    3)fetch不支持abort,不支持超時控制,使用setTimeout及Promise.reject的實現(xiàn)的超時控制并不能阻止請求過程繼續(xù)在后臺運行,造成了量的浪費
    4)fetch沒有辦法原生監(jiān)測請求的進度,而XHR可以
  1. axios
  • 從瀏覽器中創(chuàng)建 XMLHttpRequest
  • 從 node.js 發(fā)出 http 請求
  • 支持 Promise API
  • 攔截請求和響應(yīng)
  • 轉(zhuǎn)換請求和響應(yīng)數(shù)據(jù)
  • 取消請求
  • 自動轉(zhuǎn)換JSON數(shù)據(jù)
  • 客戶端支持防止CSRF/XSRF

題外話(一)

一般在項目中我們會常常遇到跨域的問題,主要受同源策略(協(xié)議,路徑,端口)的影響
尤其是使用vue-cli這種腳手架工具開發(fā)時,由于項目本身啟動本地服務(wù)是需要占用一個端口的,所以必然會產(chǎn)生跨域的問題。
在vue-cli項目中webpack的proxyTable幫我們很好的處理了跨域問題:


image.png

如何配置:在項目生成的config目錄下的index.js找
有些項目可能要接不同域名下的接口,而proxyTable支持配置多個域名,有這種需求的小伙伴可以自行配置。

劃下重點------>
axios的請求會在你的url路徑上自動拼接你的target(前提是我這種管理api的方式,后面會提)
記住我畫的那個部分(記住這個配置)

 proxyTable: {
      '/api/**': {
        target: 'http://www.itdecent.cn:8080/', //==>你的目標域名和端口
        changeOrigin: true,
        pathRewrite: {
          '^/': '/'
        }
      },
    }

主題開始

參考axios-中文使用手冊:https://www.kancloud.cn/yunye/axios/234845

一、在我們接Api的時候 主要有兩個階段

  • request 請求階段 ===》對應(yīng)了axios.interceptors.request 請求攔截器過濾請求
  • response 響應(yīng)階段 ===》對應(yīng)了axios.interceptors.response 響應(yīng)攔截器過濾響應(yīng)
    我一般在項目中建一個API文件夾 統(tǒng)一管理api 以及 axios的request的封裝方法 目錄為下


    image.png

下面直接上代碼了:

import axios from 'axios'
import { throwErr } from '@/utils' //utils 捕捉服務(wù)端http狀態(tài)碼的方法
import store from '@/store'   //引入vuex的相關(guān)操作
import { Message } from 'element-ui' //element Toast的提示
import router from '@/router'

//過濾請求
axios.interceptors.request.use(config => {
  //config 為請求的一些配置 例如:請求頭 請求時間 Token  可以根據(jù)自己的項目需求個性化配置,參考axios的中文說明手冊  自己多動動手
 //由于我們項目的后端大大給力,很多東西在服務(wù)端幫我們處理好了所以請求階段只要傳好參數(shù)就好了
  config.timeout = 10 * 1000 //請求響應(yīng)時間
  return config
}, error => {
  return Promise.reject(error)
})
// 添加響應(yīng)攔截器
axios.interceptors.response.use(
  response => {
    if (response.data.code === 0) {   //服務(wù)端定義的響應(yīng)code碼為0時請求成功
      return Promise.resolve(response.data) //使用Promise.resolve 正常響應(yīng)
    } else if (response.data.code === 1401) { //服務(wù)端定義的響應(yīng)code碼為1401時為未登錄
      store.dispatch('setUserInfo', {})
      Message({
        message: '未登錄'
      })
      // router.push('/login')
      return Promise.reject(response.data)    //使用Promise.reject 拋出錯誤和異常
    } else {
      return Promise.reject(response.data)
    }
  },
  error => {
    if (error && error.response) {
      let res = {}
      res.code = error.response.status
      res.msg = throwErr(error.response.status, error.response) //throwErr 捕捉服務(wù)端的http狀態(tài)碼 定義在utils工具類的方法
      return Promise.reject(res)
    }
    return Promise.reject(error)
  }
)
export default function request(method, url, data) {  //暴露 request 給我們好API 管理
  method = method.toLocaleLowerCase()   //封裝RESTful API的各種請求方式 以 post get delete為例
  if (method === 'post') {
    return axios.post(url, data)    //axios的post 默認轉(zhuǎn)化為json格式
  } else if (method === 'get') {     
    return axios.get(url, {
      params: data
    })
  } else if (method === 'delete') {
    return axios.delete(url, {
      params: data
    })
  }
}

以下為throwErr的源碼

//axios捕錯
export const throwErr = (code, response) => {
  let message = '請求錯誤'
  switch (code) {
    case 400:
      message = '請求錯誤'
      break
    case 401:
      message = '未授權(quán),請登錄'
      break
    case 403:
      message = '拒絕訪問'
      break
    case 404:
      message = `請求地址出錯: ${response.config.url}`
      break
    case 408:
      message = '請求超時'
      break
    case 500:
      message = '服務(wù)器內(nèi)部錯誤'
      break
    case 501:
      message = '服務(wù)未實現(xiàn)'
      break
    case 502:
      message = '網(wǎng)關(guān)錯誤'
      break
    case 503:
      message = '服務(wù)不可用'
      break
    case 504:
      message = '網(wǎng)關(guān)超時'
      break
    case 505:
      message = 'HTTP版本不受支持'
      break
    default:
  }
  return message
}

如果有的小伙伴 是'application/x-www-form-urlencoded'為請求格式的話
可以使用 npm i qs -S 使用qs包將參數(shù)序列化

  transformRequest:[function(data){
      //在這里根據(jù)自己的需求改變數(shù)據(jù)
      return qs.stringify(data,{arrayFormat:'repeat'})
    }],

二 在api管理文件夾中如何定義接口呢?

以account.js為例

  • 引入request.js
  • 暴露你定義的api接口
  • request 的三個參數(shù)(mtehod,url,params)
    1. method 及axios的請求方法 (post,get,delete ···?)
    2. url 服務(wù)端的接口路徑
      3.params 接口所傳遞的參數(shù) 全部以對象的形式傳入 (后面會提 不著急)
image.png
import request from './request' //引入axios的封裝方法

export const getAdminList = (params) => {
 return request('get', '/api/v1.0/admin/list', params) //登陸管理員獲取自身信息
}

export const register = (params) => {
 return request('post', '/api/v1.0/admin/register', params) //添加管理員
}

export const deleteAdmin = (id, params) => {
 return request('delete', `/api/v1.0/admin/${id}`, params) //更新管理員信息
}

是不是很簡單 管理的接口就是這么簡潔帥氣 為我打個call

在項目中如何使用定義的接口?

1.在頁面中import對應(yīng)的模塊api文件以及其中的接口
2.不管是哪種請求 我們?nèi)坑脤ο螅ㄦI值對)的形式傳參數(shù)
3.用async 和await 在methods中定義接口方法

  • 用來區(qū)分我們所定義的普通方法
  • 可以方便我們處理函數(shù)回調(diào) 用同步的思想寫代碼 方便理解
  • 不用.then那種鏈式寫法 美化代碼 增加可讀性和理解性
  • 配合try catch用來捕錯
image.png

此例子可以在我的上篇關(guān)于 vue mixin的文章結(jié)合觀看 觀碼效果更加
傳送門

 getParams() {
      return {
        role: this.role,
        name: this.name,
        status: this.status,
        start: (this.PAGINATION.currentPage - 1) * this.PAGINATION.pageSize,
        range: this.PAGINATION.pageSize,
      }
    },
    async getAdminList() {
      this.loading = true
      let res = await getAdminList(this.queryParams)
      this.tableData = res.data.list
      this.PAGINATION.total = res.data.count
      this.loading = false
    },
  async deleteAdmin() {
      try {
        let res = await deleteAdmin(this.id)
        this.$message({
          type: 'success',
          message: '刪除成功'
        })
        this.getAdminList()
      } catch (err) {
        this.$message({
          type: 'error',
          message: err.msg
        })
      }
    },
 addParams() {
      let { role, username, name, password, gender, profession, education, signature } = this.form
      return { role, username, name, password, gender, profession, education, signature }
    },
 async register() {
      try {
        let res = await register({ ...this.addParams() })
        this.$message({
          type: 'success',
          message: '添加成功'
        })
        this.dialogFormVisible = false
        this.$emit('listen')
      } catch (err) {
        this.$message({
          type: 'error',
          message: err.msg
        })
      }
    },

在實際表現(xiàn)如下
1.get 操作表現(xiàn)


image.png

2.delete操作表現(xiàn)


image.png

3.post 操作


image.png

題外話(二)

關(guān)于RESTful API的理解 (主要是后端開發(fā)者觀看,前端小伙伴了解即可)

精簡點:

  • http的動詞(get post delete put patch ···)描述操作
  • url地址定位資源

RESTful API:

這是一種設(shè)計風格而不是標準,只是提供了一組設(shè)計原則和約束條件。它主要用于客戶端與服務(wù)器交互類的軟件?;谶@個風格設(shè)計的軟件可以更簡潔,更有層級,更易于實現(xiàn)緩存等機制。在這種風格中,每個url路徑代表一種資源(resource),所以路徑中不推薦有名詞,而且所用的名詞往往與數(shù)據(jù)庫的表格名對應(yīng),且一般采取復數(shù)的形式命名。而對應(yīng)資源的具體操作類型,而由HTTP動詞表示,即 GET/POST/PUT/PATCH/DELETE

image.png

這是我在看書過程中所閱讀到的,具體書名就不透露了,免得有打廣告嫌疑

寫在后面

以上就是axios的二次封裝如何在項目中如何優(yōu)雅的使用,統(tǒng)一使用對象傳參的方式。我覺得這種方式很方便優(yōu)雅,因此將它分享出來,希望大家會喜歡。覺得有用的小伙伴可以給個心,給個關(guān)注,有不懂的地方可以評論我和私信我,有空會一一解答。下次會分享一篇在vue中如何將tinyMce封裝成組件,tinyMCe富文本編輯器如何上傳圖片和文件。
簡書首發(fā)網(wǎng)址

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 我們所要的說的axios的封裝和api接口的統(tǒng)一管理,其實主要目的就是在幫助我們簡化代碼和利于后期的更新維護。 一...
    kangaroo_v閱讀 8,526評論 1 67
  • Spring Cloud為開發(fā)人員提供了快速構(gòu)建分布式系統(tǒng)中一些常見模式的工具(例如配置管理,服務(wù)發(fā)現(xiàn),斷路器,智...
    卡卡羅2017閱讀 136,545評論 19 139
  • 參考AJAX 之 XHR, jQuery, Fetch 的對比[https://zhuanlan.zhihu.co...
    合肥黑閱讀 3,843評論 0 3
  • 本文詳細介紹了 XMLHttpRequest 相關(guān)知識,涉及內(nèi)容: AJAX、XMLHTTP、XMLHttpReq...
    semlinker閱讀 13,994評論 2 18
  • 【開心啟蒙】2017.9.13學習力六期踐行記錄D112 1.手指搖兩首。 2.寶玩學英語兒歌學唱十分鐘 3.指讀...
    璐璐同學閱讀 239評論 0 0

友情鏈接更多精彩內(nèi)容