新增工具函数
./src/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'
}
新增URL拼接方法
./src/helpers/url.ts
import { isDate, isObject } from './util'
function encode(val: string): string {
return encodeURIComponent(val)
.replace(/%40/g, '@')
.replace(/%3A/ig, ':')
.replace(/%24/g, '$')
.replace(/%2C/ig, ',')
.replace(/%20/g, '+')
.replace(/%5B/ig, '[')
.replace(/%5D/ig, ']')
}
export function buildURL(url: string, params?: any): string {
if (!params) {
return url
}
const parts: string[] = []
Object.keys(params).forEach(key => {
const val = params[key]
if (val === null || typeof val === 'undefined') {
return
}
let values = []
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
}
URL参数处理逻辑
// ./src/index.ts
import {AxiosRequestConfig} from './types'
import xhr from './xhr'
import { buildURL } from './helpers/url'
function axios(config: AxiosRequestConfig): void {
// TODO
processConfig(config)
xhr(config)
}
function processConfig(config: AxiosRequestConfig): void {
config.url = transformURL(config)
}
function transformURL(config: AxiosRequestConfig): string {
const { url, params } = config
return buildURL(url, params)
}
export default axios
测试
./examples/base/index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Base example</title>
</head>
<body>
<script src="/__build__/base.js"></script>
</body>
</html>
./example/base/app.ts
import axios from '../../src/index'
axios({
method: 'get',
url: '/base/get',
params: {
foo: ['bar', 'baz']
}
})
axios({
method: 'get',
url: '/base/get',
params: {
foo: {
bar: 'baz'
}
}
})
const date = new Date()
axios({
method: 'get',
url: '/base/get',
params: {
date
}
})
axios({
method: 'get',
url: '/base/get',
params: {
foo: '@:$, '
}
})
axios({
method: 'get',
url: '/base/get',
params: {
foo: 'bar',
baz: null
}
})
axios({
method: 'get',
url: '/base/get#hash',
params: {
foo: 'bar'
}
})
axios({
method: 'get',
url: '/base/get?foo=bar',
params: {
bar: 'baz'
}
})
新增链接 ./index.html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>ts-axios examples</title>
</head>
<body>
<h1>ts-axios example</h1>
<ul>
<li><a href="simple">Simple</a></li>
<li><a href="base">Base</a></li>
</ul>
</body>
</html>
新增路由 ./examples/server.js
router.get('/base/get', (req, res) => {
res.json(req.query)
})
测试
npm run dev