天天看點

手把手帶你使用 typescript 實作一個 axios 庫(一)手把手帶你使用 typescript 實作一個 axios 庫(一)

手把手帶你使用 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)
}
           

未完待續…

繼續閱讀