01
前言
相信大家在做前端开发的时候都使用过axios这款优秀的网络请求库,可以说几乎每个前后分离的项目都应该离不开他。
众所周知,在使用 javascript 开发的时候,由于语言本身的问题,对数据类型支持不是很友好,尤其是在对象字段很多的时候很容易写错,从而造成一些很难排查的bug。
好在,现在有 typescript 语言的出现弥补了 javascript的这一缺陷。然后配合着IDE很多类型的问题都会被避免。
但是typescript相对于 javascript 上手不是很容易,尤其是前期初学者,会被各种类型检查和红线而折磨甚至最后不得不回退到javascript上来。的确,在刚开始学习的时候肯定会有这样或者那样的问题,不过希望大家坚持一下只有克服了各种问题能力才能成长。
本章内容我们会介绍 typescript 中的泛型功能如何和在axios中应用。
02
ts中的泛型简单介绍
因为本节不是介绍泛型的,所以关于更多泛型介绍,这里就不多说了,只是简单介绍一下,更多的知识大家可以去 typscript 官网查一下文档。
什么是泛型呢? 泛型简单来说就是类型变量,在ts中存在类型,如number、string、boolean等。泛型就是使用一个类型变量来表示一种类型,类型值通常是在使用的时候才会设置。泛型的使用场景非常多,可以在函数、类、interface接口中使用
为什么使用泛型? TypeScript 中不建议使用 any 类型,不能保证类型安全,调试时缺乏完整的信息。 TypeScript可以使用泛型来创建可重用的组件。支持当前数据类型,同时也能支持未来的数据类型。扩展灵活,可以在编译时发现类型错误,从而保证了类型安全。
03
axios与ts泛型
在开始下面的内容的时候,先说以下几点:
1、以下axios与ts泛型的结合使用方式只是个人在VueAdminWork框架中的使用方式可能不具有广泛的代表性。不喜勿喷
2、在开始以下知识的时候,我们假定您已经具备 typescript 和 axios的相关知识
下面正式开始,我主要是以在 VueAdminWork框架的封装使用为例向大家介绍。
1.定义一个数据类型
我们以下面的数据类型为例:角色数据类型,这个比较简单好理解。
代码语言:javascript复制interface RoleModeType {
roleName: string
roleCode: string
description: string
}
2.再看一下封装的axios操作api
代码语言:javascript复制
export interface HttpOption {
url: string
data?: any
method?: string
headers?: any
beforeRequest?: () => void
afterRequest?: () => void
}
// 定义返回数据类型的泛型 T,默认值是 any
export interface Response<T = any> {
totalSize: number | 0
code: number
msg: string
data: T
}
// 定义返回数据类型的泛型 T,默认值是 any
function http<T = any>({ url, data, method, headers, beforeRequest, afterRequest }: HttpOption) {
const successHandler = (res: AxiosResponse<Response<T>>) => {
if (res.data.code === 200) {
return res.data
}
throw new Error(res.data.msg || '请求失败,未知异常')
}
const failHandler = (error: Response<Error>) => {
afterRequest && afterRequest()
throw new Error(error.msg || '请求失败,未知异常')
}
beforeRequest && beforeRequest()
method = method || 'GET'
const params = Object.assign(typeof data === 'function' ? data() : data || {}, {})
return method === 'GET'
? request.get(url, { params }).then(successHandler, failHandler)
: request.post(url, params, { headers: headers }).then(successHandler, failHandler)
}
// 定义返回数据类型的泛型 T,默认值是 any
export function get<T = any>({
url,
data,
method = 'GET',
beforeRequest,
afterRequest,
}: HttpOption): Promise<Response<T>> {
return http<T>({
url,
method,
data,
beforeRequest,
afterRequest,
})
}
// 定义返回数据类型的泛型 T,默认值是 any
export function post<T = any>({
url,
data,
method = 'POST',
headers,
beforeRequest,
afterRequest,
}: HttpOption): Promise<Response<T>> {
return http<T>({
url,
method,
data,
headers,
beforeRequest,
afterRequest,
})
}
以上代码是我个人封装的在VueAdminWork框架使用的情况,大家可以根据自己的理解进行封装。另外,这里只是封装了 `get` 和 `post` 两种请求方法,更多的请求方法可以自己再次封装。
3. 在 .vue 文件中使用
先来看一下提示功能,当然不只有提示功能这么简单,更重要的是数据安全和减少错误概率
代码语言:javascript复制const dataList = ref<Array<RoleModeType>>()
function doRefresh() {
// 在使用的时候,要指定上面我已经定义好的数据类型。
post<Array<RoleModeType>>({
url: getRoleList,
data: {},
})
.then((res) => {
// table.handleSuccess(res)
dataList.value = res.data
})
.catch(console.log)
}
可以看到 res.data 就已经是我们指定好了的 `RolaModeType[]` 类型
再来看一下如果数据类型指定不一致的情况:
代码语言:javascript复制interface RoleModeType1 {
roleName1: string
roleCode1: string
description1: string
}
const dataList = ref<Array<RoleModeType1>>()
function doRefresh() {
post<Array<RoleModeType>>({
url: getRoleList,
data: {},
})
.then((res) => {
// 这里会报错
dataList.value = res.data
})
.catch(console.log)
}
错误信息如下
04
写在最后
总的来说 typescript 中的 泛型还比较简单的,大家多用几次就可以熟练掌握,但是如果想要用好 ts ,还需要大家的不断努力。
最后我们总结一下在axios中使用泛型的几步:
1. 定义好一个数据类型
2.封装好axios的具体的操作。当然也可以不封装使用,axios已经为我们提供好了接口,可以很容易使用。
3. 在具体的 vue 组件或者页面中使用,传入具体的泛型类型
4. 最后可以通过IDE进行测试一下泛型有没有使用成功,看一下有没有提示就可以了