使用TypeScript從零重構(gòu)axios--學(xué)習(xí)總結(jié)

TypeScript 作為 JavaScript 語言的超集,它為 JavaScript 添加了可選擇的類型標(biāo)注,大大增強了代碼的可讀性和可維護性。同時,它提供最新和不斷發(fā)展的 JavaScript 特性,能讓我們建立更健壯的組件。
本篇文章主要介紹基于TypeScript從零重構(gòu)axios

  1. 處理請求 url 參數(shù)
axios({
  method: 'get',
  url: '/base/get',
  params: {
    a: 1,
    b: 2
  }
})

首先我們來分析一下怎么將多種類型的params拼接在url中。
(1)參數(shù)值為數(shù)組
最終請求的url/base/get?foo[]=bar&foo[]=baz
(2)參數(shù)值為對象
最終請求的 url 是 /base/get?foo=%7B%22bar%22:%22baz%22%7D,foo 后面拼接的是 {"bar":"baz"} encode后的結(jié)果。
(3)參數(shù)值為 Date 類型
最終請求的 url/base/get?date=2019-04-01T05:55:39.030Z,date 后面拼接的是 date.toISOString() 的結(jié)果。
(4)特殊字符支持
對于字符 @、:、$,、、[、],我們是允許出現(xiàn)在 url 中的,不希望被 encode。
最終請求的 url/base/get?foo=@:$+,注意,我們會把空格 轉(zhuǎn)換成 +。
(5)空值忽略
對于值為 null 或者 undefined 的屬性,我們是不會添加到 url 參數(shù)中的。
最終請求的 url/base/get?foo=bar
(6)丟棄 url 中的哈希標(biāo)記
最終請求的 url/base/get?foo=bar
(7)保留 url 中已存在的參數(shù)
最終請求的 url/base/get?foo=bar&bar=baz
(8)函數(shù)實現(xiàn)
helpers/url.ts:

import { isDate, isObject } from './util'

function encode (val: string): string {
  return encodeURIComponent(val)
    .replace(/%40/g, '@')
    .replace(/%3A/gi, ':')
    .replace(/%24/g, '$')
    .replace(/%2C/gi, ',')
    .replace(/%20/g, '+')
    .replace(/%5B/gi, '[')
    .replace(/%5D/gi, ']')
}

export function bulidURL (url: string, params?: any) {
  if (!params) {
    return url
  }

  const parts: string[] = []

  Object.keys(params).forEach((key) => {
    let val = params[key]
    if (val === null || typeof val === 'undefined') {
      return
    }
    let values: string[]
    if (Array.isArray(val)) {
      values = val
      key += '[]'
    } else {
      values = [val]
    }
    values.forEach((val) => {
      if (isDate(val)) {
        val = val.toISOString()
      } else if (isObject(val)) {
        val = JSON.stringify(val)
      }
      parts.push(`${encode(key)}=${encode(val)}`)
    })
  })

  let serializedParams = parts.join('&')

  if (serializedParams) {
    const markIndex = url.indexOf('#')
    if (markIndex !== -1) {
      url = url.slice(0, markIndex)
    }

    url += (url.indexOf('?') === -1 ? '?' : '&') + serializedParams
  }

  return url
}

helpers/util.ts:

const toString = Object.prototype.toString

export function isDate (val: any): val is Date {
  return toString.call(val) === '[object Date]'
}

export function isObject (val: any): val is Object {
  return val !== null && typeof val === 'object'
}

實現(xiàn) url 參數(shù)處理邏輯
我們已經(jīng)實現(xiàn)了 buildURL 函數(shù),接下來我們來利用它實現(xiàn) url 參數(shù)的處理邏輯。

在 index.ts 文件中添加如下代碼:

function axios (config: AxiosRequestConfig): void {
  processConfig(config)
  xhr(config)
}

function processConfig (config: AxiosRequestConfig): void {
  config.url = transformUrl(config)
}

function transformUrl (config: AxiosRequestConfig): string {
  const { url, params } = config
  return bulidURL(url, params)
}

在執(zhí)行 xhr 函數(shù)前,我們先執(zhí)行 processConfig 方法,對 config 中的數(shù)據(jù)做處理,除了對 url 和 params 處理之外,未來還會處理其它屬性。

在 processConfig 函數(shù)內(nèi)部,我們通過執(zhí)行 transformUrl 函數(shù)修改了 config.url,該函數(shù)內(nèi)部調(diào)用了 buildURL。

?著作權(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)容

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