美文网首页
4-1、接口扩展

4-1、接口扩展

作者: Eileen_1d88 | 来源:发表于2019-12-06 11:18 被阅读0次
需求

为了用户更加方便地使用axios,我们需要扩展一些方法

  • axios.request(config)
  • axios.get(url[, config])
  • axios.delete(url[, config])
  • axios.head(url[, config])
  • axios.options(url[, config])
  • axios.post(url[, data[, config]])
  • axios.put(url[, data[, config]])
  • axios.patch(url[, data[, config]])
    如果使用了这些方法,我们就不必一定在config中指定url,method,data这些属性了。
    从需求上看,axios不单单是一个方法,更像是一个混合对象,本身是一个方法,同时又拥有很多方法属性。接下来我们来实现这个混合对象。
创建Axios接口
interface Axios {
  request(config: AxiosRequestConfig): AxiosPromise
  get(url: string, config?: AxiosRequestConfig): AxiosPromise
  head(url: string, config?: AxiosRequestConfig): AxiosPromise
  delete(url: string, config?: AxiosRequestConfig): AxiosPromise
  options(url: string, config?: AxiosRequestConfig): AxiosPromise
  put(url: string, data?: any, config?: AxiosRequestConfig): AxiosPromise
  post(url: string, data?: any, config?: AxiosRequestConfig): AxiosPromise
  patch(url: string, data?: any, config?: AxiosRequestConfig): AxiosPromise
}
创建Axios类

src/core/Axios.ts

import { AxiosRequestConfig, AxiosPromise, Method } from "../types";
import dispatchRequest from "./dispatchRequest";

export default class Axios {
  request(config: AxiosRequestConfig): AxiosPromise {
    return dispatchRequest(config)
  }
  get(url: string, config?: AxiosRequestConfig): AxiosPromise {
    return this._requestMethod(url, 'get', config)
  }
  delete(url: string, config?: AxiosRequestConfig): AxiosPromise {
    // const newConfig = Object.assign(config || {}, {
    //   url,
    //   method: 'delete'
    // })
    // return dispatchRequest(newConfig)
    return this._requestMethod(url, 'delete', config)
  }
  head(url: string, config?: AxiosRequestConfig): AxiosPromise {
    return this._requestMethod(url, 'head', config)
  }
  options(url: string, config?: AxiosRequestConfig): AxiosPromise {
    return this._requestMethod(url, 'options', config)
  }
  put(url: string, data?: any, config?: AxiosRequestConfig,): AxiosPromise {
    return this._requestMethod(url, 'put', config, data)
  }
  post(url: string, data?: any, config?: AxiosRequestConfig,): AxiosPromise {
    return this._requestMethod(url, 'post', config, data)
  }
  patch(url: string, data?: any, config?: AxiosRequestConfig,): AxiosPromise {
    return this._requestMethod(url, 'patch', config, data)
  }
  _requestMethod(url: string, method: Method, config?: AxiosRequestConfig, data?: any) {
    const newConfig = Object.assign(config || {}, {
      url,
      method,
      data: data || null
    })
    return this.request(newConfig)
  }
}

src/axios.ts

import Axios from './core/Axios'
const axios = new Axios()
export default axios

但是单单这样做有一个问题,就是axios方法是可以直接像这样使用的:

axios({...config})

但是显然我们上面的实现不能达到这个目的,所以我们需要做进一步的处理。

创建AxiosInstance接口
interface AxiosInstance extends Axios {
  (config: AxiosRequestConfig): AxiosPromise
}

AxiosInstance继承Axios接口,那么它就是一个混合接口
src/axios.ts

import { AxiosInstance } from "./types";
import Axios from './core/Axios'
import { extend } from "./helpers/util";
function createInstance() {
  const context = new Axios()
  const instance = Axios.prototype.request.bind(context)
  extend(instance, context)
  return instance as AxiosInstance
}
const axios = createInstance()
export default axios

src/healpers/util.ts

function extend<T, U>(to: T, from: U): T & U {
  for (const key in from) {
    ;(to as T & U)[key] = from[key] as any
  }
  return to as T & U
}

拥有axios方法的instance,也获取到axios的属性方法,这样axios除了可以使用axios.get, axios.put等方法,也可以直接使用axios(config)。

编写demo
import axios from '../../src/index'

axios({
  url: '/extend/post',
  method: 'post',
  data: {
    msg: 'hi'
  }
})

axios.request({
  url: '/extend/post',
  method: 'post',
  data: {
    msg: 'hello'
  }
})

axios.get('/extend/get')

axios.options('/extend/options')

axios.delete('/extend/delete')

axios.head('/extend/head')

axios.post('/extend/post', { msg: 'post' })

axios.put('/extend/put', { msg: 'put' })

axios.patch('/extend/patch', { msg: 'patch' })

至此,我们支持了对axios API的扩展,把它变成了一个混合对象。官方的axios实例,除了支持axios(config)外,还支持传入2个参数axios(url, config),这里就涉及到函数重载的概念,接下来我们来实现这个功能。

相关文章

网友评论

      本文标题:4-1、接口扩展

      本文链接:https://www.haomeiwen.com/subject/qhkjgctx.html