小知识,大挑战!本文正在参与「程序员必备小知识」创作活动
确定结构
首先我们知道axios 有下面两种调用方式,作为一个函数或者作为类。
import axios from 'axios'
axios.get('/user?ID=12345')
let a= axios({
method:'get',
url:'/user?ID=12345',
})
还可以添加拦截器
axios.interceptors.request.use((config) => {
config={};
return config
});
按照上面的使用情况,如果我们直接定义下面的结构的话,可以实现上面的调用。
function axios(config) {
this.config = config
request.apply(this);
}
axios.get = function (config) {
request.bind(this.config, this.interceptors);
}
axios.interceptors = []
let request = function () {
console.log(this.config, this.interceptors)
}
但是你会发现interceptors,无法使用.
所以在Axios源码中,并不是直接抛出一个axios类或者axios函数,而是抛出一个Axios.prototype.request的实例 axios本身是一个函数,上面挂在这get post等方法以及Axios类.而且Axios.prototype 也挂在着get post 之类的请求。
定义Axios类
src\core\Axios.ts
import InterceptorManager from './InterceptorManager'
import xhr from '../adapter/xhr'
import { requestConfig } from '../types/index'
function Axios(instanceConfig?: any): void {
this.defaults = instanceConfig;
this.interceptors = {
request: new InterceptorManager(),
response: new InterceptorManager()
};
}
Axios.prototype.request = function (config:requestConfig) {
console.log('我是request请求')
xhr(config)
}
Axios.prototype.get=function(config:requestConfig){
Axios.prototype.request(config)
}
Axios.prototype.post=function(config:requestConfig){
Axios.prototype.request(config)
}
export default Axios;
导出axios
import Axios from './core/Axios'
// axios原型挂载
function createInstance() {
const AxiosTemp = new Axios()
// 创建request实例,并且绑定Axios实例为上下文this
const instance = Axios.prototype.request.bind(AxiosTemp)
// for循环是为了将Axios.prototye上的get post方法挂载到instance上
for (const key in Axios.prototype) {
if (typeof Axios.prototype[key] === 'function') {
instance[key] = Axios.prototype[key].bind(AxiosTemp)
} else {
instance[key] = Axios.prototype[key]
}
}
// for循环是为了将Axios上的default,interceptors挂载到instance上
for (const key in AxiosTemp) {
if (typeof Axios[key] === 'function') {
instance[key] = AxiosTemp[key].bind(AxiosTemp)
} else {
instance[key] = AxiosTemp[key]
}
}
instance.Axios=Axios
return instance
}
const axios = createInstance()
export default axios;
新建type
src\types\index.ts
export interface requestConfig {
url:string,
method:string
data?:any // post的参数 ? 可选
params?:any // get的参数 ? 可选
}
测试
-
执行yarn build 打包
-
执行yarn test 启动服务
-
example\index.html
<script src="../../dist/index.umd.js"></script> <script> console.dir(axios) </script> -
测试结果 OK!!!