手把手帶你使用 typescript 實作一個 axios 庫(一)
注:本教程基于慕課網黃大神的課程進行的整理
源碼位址
前言
本人是個工作一年多的前端小菜鳥,熱愛寫代碼,喜歡分享。近期在學習黃大神的課程,就想着寫部落格來記錄一下,一方面加深自己的了解,一方面分享出來給需要的人
需求分析
我們要做的是用 typescript 來重構 axios,so 你需要先熟悉axios,此次重構,會支援以下功能。
- 在浏覽器端使用 XMLHttpRequest 對象通訊
- 支援 Promise API
- 支援請求和響應的攔截器
- 支援請求資料和響應資料的轉換
- 支援請求的取消
- JSON 資料的自動轉換
- 用戶端防止 XSRF
項目初始化
這裡我們使用 typescript 的一個腳手架工具typescript-library-starter,感興趣的可以點選進去進一步學習。
前言
如果你還不了解typescript,可以先看一下官網的5分鐘上手TypeScript這篇文章
使用方式
git clone https://github.com/alexjoverm/typescript-library-starter.git ts-axios-pro
cd ts-axios-pro
npm install
// 如果npm安裝慢的話,可以用如下指令替換為國内的淘寶源
npm install --registry=https://registry.npm.taobao.org
目錄結構
├── CONTRIBUTING.md
├── LICENSE
├── README.md
├── code-of-conduct.md
├── node_modules
├── package-lock.json
├── package.json
├── rollup.config.ts // rollup 配置檔案
├── src // 源碼目錄
├── test // 測試目錄
├── tools // 釋出到 GitHup pages 以及 釋出到 npm 的一些配置腳本工具
├── tsconfig.json // TypeScript 編譯配置檔案
└── tslint.json // TypeScript lint 檔案
基礎請求代碼的實作
先看一個基礎的請求,我們通過傳入一個對象來發送請求。
axios({
method: 'get',
url: '/simple/get',
params: {
a: 1,
b: 2
}
})
建立入口檔案
在src目錄下建立一個index.ts檔案用來作為我們的入口檔案。如果你仔細觀察了上面的axios請求,不難寫出如下的代碼
function axios(config) {
}
export default axios
此時,你的編輯器會給你一個紅色的波浪線警告和一個綠色的警告(如果沒有,請安裝TSlint插件),滑鼠移上去會顯示錯誤資訊。如下圖…
這裡是圖檔
移到config上會展示
1、已聲明“config”,但從未讀取其值。ts(6133)
參數“config”隐式具有“any”類型。ts(7006)
2、移到綠色的那裡會告訴你這個函數不能為空
原因:預設在tsconfig.json檔案中吧strict設定為了true(建議開啟,不要吧它設定成false)
解決方法:給config定義接口類型
建立類型檔案(type)
在src目錄下建立一個
types
目錄,在下面建立一個index.ts類型定義檔案。
定義一個AxiosRequestConfig接口類型
export interface AxiosRequestConfig {
url: string
method: string
data?: any // 可選參數用?号表示
params?: any
}
其中
url
,
data
,
params
這三者都是使用者随機填寫的,但是
method
是固定為
get
、
post
、
put
等。
so我們這裡需要把
method
的類型改寫為字元串字面量類型。
接下來我們改寫上面的代碼如下
export type Method = 'get' | 'GET'
| 'delete' | 'DELETE'
| 'head' | 'HEAD'
| 'options' | 'OPTIONS'
| 'post' | 'POST'
| 'put' | 'PUT'
| 'patch' | 'PATCH'
export interface AxiosRequestConfig {
url: string
method: Method
data?: any
params?: any
}
這樣限制了輸入的method隻能為指定的字元串
scr
下的
index.ts
為
import { AxiosRequestConfig } from './types'
function axios(config: AxiosRequestConfig) {
// aaa
}
export default axios
此時,就不會有警告資訊
編寫原生ajax請求代碼
我們利用子產品化的思想,将這部分邏輯拆分為一個單獨的ts檔案。在
src
目錄下建立一個
xhr.ts
檔案,内容如下
import { AxiosRequestConfig } from './types' // 引入config類型定義
// void: 它表示沒有任何類型。 當一個函數沒有傳回值時,你通常會見到其傳回值類型是 void:
export default function xhr(config: AxiosRequestConfig): void {
const { url, method = 'get', data = null } = config // 從config中解構出url,method, data 參數
// 建立XMLHttpRequest對象
const request = new XMLHttpRequest()
/**
* @description: 發送
* @param method {String} 請求方式
* @param url { String} 請求url
* @param async {Boolean} 是否異步
*/
request.open(method.toUpperCase(), url, true)
request.send(data)
}
未完待續…