“这是我参与8月更文挑战的第20天,活动详情查看:8月更文挑战”
本文主要介绍基于TS和AXIOS的接口请求封装
思路
-
请求拦截
- 在请求头添加一些参数,例如token,uid等
- 判断用户登录状态,如果没有登录,直接跳转登录
- 处理请求数据转换发送请求的数据格式,json→urlencoded (可选的)
-
响应拦截
-
判断后端响应的业务状态码,进行不同的处理
- 例如用户登录状态过期,直接跳转登录
- 统一的报错提示
-
先把套路化的代码写出来:
import axios, {
AxiosInstance,
AxiosResponse,
AxiosRequestConfig,
AxiosError
} from 'axios'
export default abstract class HttpClient {
protected readonly instance: AxiosInstance
public constructor(baseURL = '/api', timeout = 1000 * 120) {
this.instance = axios.create({
baseURL,
timeout
})
// 1. 请求拦截器
this._initializeRequestInterceptor()
// 2. 响应拦截器
this._initializeResponseInterceptor()
}
private _initializeRequestInterceptor = () => {
this.instance.interceptors.request.use(
this._handleRequest,
this._handleError
)
}
private _handleRequest = (config: AxiosRequestConfig) => {}
private _initializeResponseInterceptor = () => {
this.instance.interceptors.response.use(
this._handleResponse,
this._handleError
)
}
private _handleResponse = (response: AxiosResponse) => {}
protected _handleError = (error: AxiosError) => Promise.reject(error)
}
简单说一下上面的代码,我们创建了一个用于请求接口的HttpClient类,在constructor中定义了baseURL
和超时时间timeout,同时定义了请求拦截方法和响应拦截方法。
至此,发起一个接口的流程如下:
- 发送请求之前,调用请求拦截
- 发送接口,network出现请求
- 接口响应,调用响应拦截
- 响应给前端程序,执行对应的逻辑
请求拦截
下面开始详细的逻辑,请求拦截的时候,可以做的事情如下:
- 在请求头添加一些参数,例如token,uid等
- 判断用户登录状态,如果没有登录,直接跳转登录
- 处理请求数据转换发送请求的数据格式,json→urlencoded (可选的)
private _handleRequest = (config: AxiosRequestConfig) => {
//1. 添加自定义请求头
config.headers['Authorization'] = 'my token'
config.headers['mobile'] = 'my mobile'
//2. 判断是否登录(判断是否有toke)
//3. 转化数据格式
config.data = qs.stringify(config.data)
return config
}
响应拦截
得到了响应之后,处理如下:
- 判断后端响应的业务状态码,进行不同的处理
- 如果用户登录状态过期,直接跳转登录
- 统一的报错提示
- 保存token
// 响应拦截器
private _handleResponse = (response: AxiosResponse) => {
const { data, headers } = response
//1.--处理响应的token,保存token
const token = headers['authorization']
if (token) {
this._saveToken(token)
}
//2. --处理响应码,这里try-catch一下,如果后端有的接口没有返回code,直接返回
try {
const code = data.code,
message = data.desc || data.msg
const isSucceed = this._handleResCode(code, message, url)
if (isSucceed) {
return Promise.resolve(data)
} else {
return Promise.reject(message)
}
} catch (error) {
return Promise.resolve(data)
}
}
//保存token
private _saveToken(token: string) {
const USER = getModule(UserModule)
USER.setToken(token)
}
private _handleResCode(code: number, message: string, url: string) {
if (code === 0) {
// 请求成功
return true
} else if (code===4000) {
// token失效,跳回登录界面
Vue.prototype.$message.error('身份信息过期,请重新登陆')
router.push({ name: 'login' })
return false
} else {
// 其他情况,统统提示message信息
Vue.prototype.$message.error(message)
return false
}
}
使用httpClient.ts定义请求
建议请求相关的文件定义在@/api目录下面,目录如下
httpClient.ts
user.ts
uti.ts
在对应的文件中定义请求,注意事项
- 所有请求类需要继承
HttpClient
类,HttpClient做了一些统一拦截统一处理请求及响应的工作 - 请求响应的数据需要提供类型,类型定义在
@/types/xxx
文件中,一个模块对应一个文件。只有提供了类型,才会有代码提示
import HttpClient from './HttpClient'
import { AlarmItemType } from '../types/test'
import { BaseResType } from '../types/index'
class UtilApi extends HttpClient {
//例如后台返回的响应 res={code:xxx,data:xxx,token:xxx,desc:xxx}
//首先需要定义 res.data 的类型 即get的第一个参数 AlarmItemType
//然后需要定义整个响应的类型 即 BaseResType<AlarmItemType>
public getAlarmById = (id: string) =>
this.instance.get<AlarmItemType, BaseResType<AlarmItemType>>(
`/realtime/alarms/queryByAlarmId/${id}`
)
}
export const UTIL_API = new UtilApi()
在组件中请求接口
在需要发送请求的组件中键入请求模块的关键字,例如USER_API
,如果安装了插件TypeScript Importer
,就会有相应的模块导入提示,此时输入回车即可导入相应的模块。
<template>
<section>请求数据:{{ alarmData }}</section>
</template>
<script lang="ts"> import { UTIL_API } from '@/api/utilApi' import { Vue, Component } from 'vue-property-decorator' @Component({ components: {} }) export default class TestRequest extends Vue { alarmData = {} async getAlarmData() { const res = await UTIL_API.getAlarmById('alarmIdc7e9bd47') if (res.code == 0) { this.$message.success('请求成功') this.alarmData = res.data } } mounted() { this.getAlarmData() } } </script>
<style lang="scss" scoped></style>
今天的文章基于Typescript和Axios的接口请求管理分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/23319.html