手把手帶你使用 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) } 複製程式碼
未完待續...