我造了一个轮子:Norm Axios(约定式请求)

发这篇文章的目的

  1. 介绍一下该库。
  2. 求建议,欢迎大佬们拍砖提建议!

为什么写这个库

在日常开发中一个项目可能接入多个后端,而且后端返回的数据结构不一致

  • 有的接口返回 { 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>

文档

更多功能请查看文档

相关推荐
January120742 分钟前
【AI方法笔记】2026-11-02:模型流式吐 JSON 时,前端会遇到四种崩法
前端·人工智能·笔记·json
asdzx671 小时前
C# 操作 PDF 元数据:从属性写入到字段提取的完整流程
前端·pdf·c#
吹什么轩1 小时前
constexpr 完全指南:从 const 的两种含义,到编译期计算的四次演进
java·前端·javascript
小蒜学长1 小时前
基于SpringBoot+Vue的云南地区扶贫助农系统的设计与实现(代码+数据库+LW)
java·vue.js·spring boot·后端·乡村振兴
Bruce_Liuxiaowei2 小时前
前端校验登录态,等于没校验——一次应急广播终端高危漏洞的发现与报送
运维·前端·安全
Meta Luo2 小时前
AI 时代,Web 自动化测试该怎么做?
前端·人工智能·playwright 替代工具·无代码自动化测试工具·低代码 ui 自动化测试·web 回归测试工具
去伪存真2 小时前
AI Agent 性能评估指标与自动化测试落地方案
前端·agent
MaAidan2 小时前
用 Agent 排查线上问题:SLS 日志分析 + DB/Redis 数据验证,一条链路搞清楚
前端·bootstrap·html
墨林陌2 小时前
AI 热点日报(2026-11-03):美团发布 1.6 万亿参数国产大模型,四大厂商共推 AI 训练退出标准
前端
Moment3 小时前
DeepSeek 发布新模型,直接把 Agent 联网搜索的门槛打下来了!
前端·后端