发这篇文章的目的
- 介绍一下该库。
- 求建议,欢迎大佬们拍砖提建议!
为什么写这个库
在日常开发中一个项目可能接入多个后端,而且后端返回的数据结构不一致
- 有的接口返回
{ code, data, message }
- 有的返回
{ status, result, msg }
这就导致前端需要写大量重复、琐碎的代码去解析响应、提取数据、处理异常 ,甚至为了兼容不同格式还要加各种 if
判断,让请求逻辑越来越"乱"。我们可以NormAxios
来解决这个问题。
同时我们可以搭配useRequest
和usePagination
来使用
-
使用
useRequest
可以简化数据获取流程,自动处理请求状态,减少了冗余代码。 -
使用
usePagination
可以简化分页处理,自动管理分页状态,减少了手动编写分页逻辑的麻烦。
只有一个后端也能使用该库
使用
简单介绍一下使用方式
安装
shell
npm install axios norm-axios
定义后台响应结构
定义俩个不一样的数据结构
服务 A
ts
interface ResultA<TData> {
code: number,
message: string
data: TData
}
服务 B
ts
interface ResultB<TData> {
status: number,
msg: string
result: TData
}
创建请求
实例A
typescript
import { NormAxios, ResponseContent } from 'norm-axios'
const serverA = new NormAxios<ResultA>({
baseURL: '/serviceA',
timeout: 10000,
interceptor: {
// 处理请求之前(比如请求头、token)
onBeforeRequest(config) {
return config
},
// 处理响应
onResponse(response) {
// 服务响应数据
const { code, message, data } = response.data
// 统一的响应结果
const responseContent: ResponseContent<Result, typeof result> = [ data, undefined, response ]
// 处理响应错误 (假设 code 不等于 200 为错误)
if (code !== 200) {
// 设置错误的响应内容
responseContent[1] = { code, msg:message }
}
return responseContent
},
// 处理响应错误
onResponseError(error) {
const responseContent: ResponseContent = [ undefined, undefined, err.response ]
// 处理响应后的错误
if (err.response) {
// 请求已发出,但服务器响应的状态码错误
responseContent[1] = { code: err.response.status, msg: '请求错误' }
}
// 处理请求时的错误
else {
responseContent[1] = { code: err.code as number, msg: '请求错误', axiosError: err }
}
return responseContent
},
},
})
实例B
typescript
import { NormAxios, ResponseContent } from 'norm-axios'
const serverB = new NormAxios<ResultB>({
baseURL: '/serviceB',
timeout: 10000,
interceptor: {
// 处理请求之前(比如请求头、token)
onBeforeRequest(config) {
return config
},
// 处理响应
onResponse(response) {
// 服务响应数据
const { status, msg, result } = response.data
// 统一的响应结果
const responseContent: ResponseContent<Result, typeof result> = [ result, undefined, response ]
// 处理响应错误 (假设 status 不等于 200 为错误)
if (status !== 200) {
// 设置错误的响应内容
responseContent[1] = { code:status, msg }
}
return responseContent
},
// 处理响应错误
onResponseError(error) {
const responseContent: ResponseContent = [ undefined, undefined, err.response ]
// 处理响应后的错误
if (err.response) {
// 请求已发出,但服务器响应的状态码错误
responseContent[1] = { code: err.response.status, msg: '请求错误' }
}
// 处理请求时的错误
else {
responseContent[1] = { code: err.code as number, msg: '请求错误', axiosError: err }
}
return responseContent
},
},
})
定义 API
typescript
interface Userinfo {
name: string
age: number
}
// 使用服务A定义 API
// 获取用户信息
const getUserinfo = (id) => serverA.get<Userinfo>('/userinfo', { id })
// 使用服务B定义 API
// 获取用户列表
const getUserList = (params) => serverB.post<Userinfo[]>('/userlist', params)
常规使用
typescript
const setUserinfo = async (id) => {
const [ data, err, res ] = await getUserinfo(id)
if (err) {
// 处理错误
}
console.log(data) // 取的是后台响应内容的 data
console.log(res) // axios响应体(包含请求头、响应头、实际响应内容之类)
}
搭配 useRequest
使用
html
<template>
<div>
<div v-if="loading">加载中...</div>
<div v-if="error">异常啦</div>
<div v-if="data">数据(取的是后台响应内容的 data): {{ data }}</div>
<div v-if="rawData">原始数据(包含 code、msg、data): {{ rawData }}</div>
<div v-if="response">axios 响应内容: {{ response }}</div>
</div>
</template>
<script lang="ts" setup>
import { useRequest } from 'norm-axios'
const { data, loading, error, rawData, response } = useRequest(getUserinfo)
</script>
搭配 usePagination
使用
html
<template>
<div>
<div v-if="loading">加载中...</div>
<div v-if="error">异常啦</div>
<div v-if="list">列表数据(取的是后台响应内容data中的 list): {{ list }}</div>
<div v-if="rawData">原始数据(包含 code、msg、data): {{ rawData }}</div>
<div v-if="response">axios 响应内容: {{ response }}</div>
<div v-if="page">当前分页: {{ page }}</div>
<div v-if="pageSize"> 每页数量: {{ pageSize }}</div>
<div v-if="total"> 列表总数: {{ total }}</div>
<div v-if="totalPage"> 分页总数: {{ totalPage }}</div>
</div>
</template>
<script lang="ts" setup>
import { usePagination } from 'norm-axios'
const {
list,
loading,
error,
rawData,
response,
page,
pageSize,
total,
totalPage,
} = usePagination(({ page, pageSize }) => getUserList({ page, pageSize }))
</script>
文档
更多功能请查看文档
- Github: github.com/songpeng154...
- 项目文档: norm-axios-press.pages.dev