axios 二次封裝 api的統籌管理 配合async await實際專案中的運用
寫在前面
作者簡書地址
axios在實戰專案中的運用,所舉例專案是基於vue全家桶(vue-router+vuex+axios+element-ui)的後臺管理系統,需要一些有vue專案開發經驗的讀者閱讀。
由於vue-resource 作者宣佈不再更新,促使我們使用第三方的request資料請求,一般我們的選擇有
- JQuery ajax
- 本身是針對MVC的程式設計,不符合現在前端MVVM的浪潮
- 基於原生的XHR開發,XHR本身的架構不清晰,已經有了fetch的替代方案
- JQuery整個專案太大,單純使用ajax卻要引入整個JQuery非常的不合理(採取個性化打包的方案又不能享受CDN服務)
- fetch
- 符合關注分離,沒有將輸入、輸出和用事件來跟蹤的狀態混雜在一個物件裡
更好更方便的寫法 - 更加底層,提供的API豐富(request, response)
- 脫離了XHR,是ES規範裡新的實現方式
1)fetchtch只對網路請求報錯,對400,500都當做成功的請求,需要封裝去處理
2)fetch預設不會帶cookie,需要新增配置項
3)fetch不支援abort,不支援超時控制,使用setTimeout及Promise.reject的實現的超時控制並不能阻止請求過程繼續在後臺執行,造成了量的浪費
4)fetch沒有辦法原生監測請求的進度,而XHR可以
- axios
- 從瀏覽器中建立 XMLHttpRequest
- 從 node.js 發出 http 請求
- 支援 Promise API
- 攔截請求和響應
- 轉換請求和響應資料
- 取消請求
- 自動轉換JSON資料
- 客戶端支援防止CSRF/XSRF
題外話(一)
一般在專案中我們會常常遇到跨域的問題,主要受同源策略(協議,路徑,埠)的影響
尤其是使用vue-cli這種腳手架工具開發時,由於專案本身啟動本地服務是需要佔用一個埠的,所以必然會產生跨域的問題。
在vue-cli專案中webpack的proxyTable幫我們很好的處理了跨域問題:
如何配置:在專案生成的config目錄下的index.js找
有些專案可能要接不同域名下的介面,而proxyTable支援配置多個域名,有這種需求的小夥伴可以自行配置。
劃下重點------>
axios的請求會在你的url路徑上自動拼接你的target(前提是我這種管理api的方式,後面會提)
記住我畫的那個部分(記住這個配置)
proxyTable: {
'/api/**': {
target: 'https://www.jianshu.com:8080/', //==>你的目標域名和埠
changeOrigin: true,
pathRewrite: {
'^/': '/'
}
},
}
主題開始
參考axios-中文使用手冊:https://www.kancloud.cn/yunye/axios/234845
一、在我們接Api的時候 主要有兩個階段
- request 請求階段 ===》對應了axios.interceptors.request 請求攔截器過濾請求
-
response 響應階段 ===》對應了axios.interceptors.response 響應攔截器過濾響應
我一般在專案中建一個API資料夾 統一管理api 以及 axios的request的封裝方法 目錄為下
下面直接上程式碼了:
import axios from 'axios'
import { throwErr } from '@/utils' //utils 捕捉服務端http狀態碼的方法
import store from '@/store' //引入vuex的相關操作
import { Message } from 'element-ui' //element Toast的提示
import router from '@/router'
//過濾請求
axios.interceptors.request.use(config => {
//config 為請求的一些配置 例如:請求頭 請求時間 Token 可以根據自己的專案需求個性化配置,參考axios的中文說明手冊 自己多動動手
//由於我們專案的後端大大給力,很多東西在服務端幫我們處理好了所以請求階段只要傳好引數就好了
config.timeout = 10 * 1000 //請求響應時間
return config
}, error => {
return Promise.reject(error)
})
// 新增響應攔截器
axios.interceptors.response.use(
response => {
if (response.data.code === 0) { //服務端定義的響應code碼為0時請求成功
return Promise.resolve(response.data) //使用Promise.resolve 正常響應
} else if (response.data.code === 1401) { //服務端定義的響應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 捕捉服務端的http狀態碼 定義在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 預設轉化為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 = '未授權,請登入'
break
case 403:
message = '拒絕訪問'
break
case 404:
message = `請求地址出錯: ${response.config.url}`
break
case 408:
message = '請求超時'
break
case 500:
message = '伺服器內部錯誤'
break
case 501:
message = '服務未實現'
break
case 502:
message = '閘道器錯誤'
break
case 503:
message = '服務不可用'
break
case 504:
message = '閘道器超時'
break
case 505:
message = 'HTTP版本不受支援'
break
default:
}
return message
}
如果有的小夥伴 是'application/x-www-form-urlencoded'為請求格式的話
可以使用 npm i qs -S 使用qs包將引數序列化
transformRequest:[function(data){
//在這裡根據自己的需求改變資料
return qs.stringify(data,{arrayFormat:'repeat'})
}],
二 在api管理資料夾中如何定義介面呢?
以account.js為例
- 引入request.js
- 暴露你定義的api介面
- request 的三個引數(mtehod,url,params)
- method 及axios的請求方法 (post,get,delete ···Ï)
- url 服務端的介面路徑
3.params 介面所傳遞的引數 全部以物件的形式傳入 (後面會提 不著急)
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對應的模組api檔案以及其中的介面
2.不管是哪種請求 我們全部用物件(鍵值對)的形式傳引數
3.用async 和await 在methods中定義介面方法
- 用來區分我們所定義的普通方法
- 可以方便我們處理函式回撥 用同步的思想寫程式碼 方便理解
- 不用.then那種鏈式寫法 美化程式碼 增加可讀性和理解性
- 配合try catch用來捕錯
此例子可以在我的上篇關於 vue mixin的文章結合觀看 觀碼效果更加
傳送門
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
})
}
},
在實際表現如下
1.get 操作表現
2.delete操作表現
3.post 操作
題外話(二)
關於RESTful API的理解 (主要是後端開發者觀看,前端小夥伴瞭解即可)
精簡點:
- http的動詞(get post delete put patch ···)描述操作
- url地址定位資源
RESTful API:
這是一種設計風格而不是標準,只是提供了一組設計原則和約束條件。它主要用於客戶端與伺服器互動類的軟體。基於這個風格設計的軟體可以更簡潔,更有層級,更易於實現快取等機制。在這種風格中,每個url路徑代表一種資源(resource),所以路徑中不推薦有名詞,而且所用的名詞往往與資料庫的表格名對應,且一般採取複數的形式命名。而對應資源的具體操作型別,而由HTTP動詞表示,即 GET/POST/PUT/PATCH/DELETE
這是我在看書過程中所閱讀到的,具體書名就不透露了,免得有打廣告嫌疑
寫在後面
以上就是axios的二次封裝以及如何在專案中如何優雅的使用,統一使用物件傳參的方式。我覺得這種方式很方便優雅。因此將它分享出來,希望大家會喜歡。覺得有用的小夥伴可以給個心,給個關注,有不懂的地方可以評論我和私信我,有空會一一解答。下次會分享一篇在vue中如何將tinyMce封裝成元件,tinyMCe富文字編輯器如何上傳圖片和檔案。
發現簡書的百度seo不怎麼好而且不防爬蟲,第二天搜尋自己的標題發現文章在其它網站上而且是第一條,根本搜不到自己的
簡書首發網址
相關文章
- axios的二次封裝與async,await的配合使用?iOS封裝AI
- 使用async await 封裝 axiosAI封裝iOS
- vue中Axios的封裝和API介面的管理(更新)VueiOS封裝API
- axios的二次封裝iOS封裝
- vue axios封裝以及API統一管理VueiOS封裝API
- 詳解vue中Axios的封裝與API介面的管理VueiOS封裝API
- 專案中的運籌帷幄
- axios二次封裝iOS封裝
- axios封裝apiiOS封裝API
- MVVM+RAC實際專案中的運用MVVM
- 使用promise封裝jquery的ajax來實現async和await方式Promise封裝jQueryAI
- 在RN專案上對axios的封裝iOS封裝
- axios二次封裝學習iOS封裝
- vue-axios的總結及專案中的常見封裝方法。VueiOS封裝
- vue全家桶 ---axios的使用和二次封裝VueiOS封裝
- 淺談專案管理在電廠實際運營管理的應用(1)(轉)專案管理
- 淺談專案管理在電廠實際運營管理的應用(2)(轉)專案管理
- [譯] 如何在實際開發案例中掌握 Async/AwaitAI
- vue中axios請求的封裝VueiOS封裝
- vue中axios的使用與封裝VueiOS封裝
- Vue合理配置axios並在專案中進行實際應用?VueiOS
- 【譯】JavaScript中的async/awaitJavaScriptAI
- notification 全解和 api 的二次封裝API封裝
- Google Guava 在實際場景中的應用封裝GoGuava封裝
- MVP 在專案中的最佳實戰(封裝篇)MVP封裝
- 關於MVP分層架構在專案中的實際運用MVP架構
- Nuxt配合Node在實際生產中的應用UX
- vue介面請求方式axios二次封裝VueiOS封裝
- Vue二次封裝axios為外掛使用Vue封裝iOS
- JavaScript中的async/await詳解JavaScriptAI
- Vue中async await的使用示例VueAI
- 理解C#中的 async awaitC#AI
- async和await的使用總結 ~ 竟然一直用錯了c#中的async和await的使用。。AIC#
- Rust 標準庫中的 async/await (async-std)RustAI
- 把JBPM運用到實際專案中(1)
- Vue Axios 的封裝使用VueiOS封裝
- 在你的專案管理中,運用報表分析了嗎?專案管理
- 專案管理在HIS專案實施中的應用(轉)專案管理