Skip to content

fetchRequest

基于 fetch 封装的请求工具方法

引入版本

0.65.0

使用示例

在App.vue入口统一初始化

js
import { setFetchGlobalConfig } from '@wyfex/iutils'
import { ElMessage } from 'element-plus'
import { useUserStore } from '@/stores/user'

const userStore = useUserStore()

// ===================== 全局请求统一配置 =====================
const initFetchGlobalSetting = () => {
  setFetchGlobalConfig({
    baseHeaders: {
      'Content-Type': 'application/json;charset=utf-8',
      // 初始带上token
      token: userStore.token
    },
    // 【全局统一错误处理器】所有接口异常统一走这里
    globalErrorHandler: (err: unknown, url: string) => {
      const error = err as Error
      console.error(`[请求异常] ${url}`, error.message)

      // 场景1:401 登录失效,跳转登录页
      if (error.message.includes('状态【401】')) {
        ElMessage.error('登录已失效,请重新登录')
        userStore.clearToken()
        // 跳转登录
        location.href = '/login'
        return
      }

      // 场景2:请求主动取消,不弹窗
      if (error.name === 'AbortError') return

      // 场景3:通用错误提示
      ElMessage.error(error.message || '服务器请求失败')
    }
  })
}
initFetchGlobalSetting()

// 亦可在登录成功后端返回token后手动执行setFetchGlobalConfig
watch(
  () => userStore.token,
  (newToken) => {
    setFetchGlobalConfig({ baseHeaders: { token: newToken } })
  }
)

接口定义示例 src/api/demo.ts

js
import {
  createGetApi,
  createPostApi,
  createPutApi,
  createDeleteApi
} from '@wyfex/iutils'

// ---------------- GET 示例 ----------------
// GET 无参数
export const getSystemInfoApi = createGetApi('/api/system/info')
// GET 带参数(默认开启防重复)
export const getTableListApi = createGetApi('/api/table/list')
// GET 长轮询接口,永久关闭防重复
export const getStreamDataApi = createGetApi('/api/stream/poll', {
  skipDeduplicate: true
})

// ---------------- POST 示例 ----------------
// POST 无参数
export const postLogoutApi = createPostApi('/api/user/logout')
// POST 带请求体
export const saveGoodsApi = createPostApi('/api/goods/save')

// ---------------- PUT 示例 ----------------
export const editGoodsApi = createPutApi('/api/goods/edit')

// ---------------- DELETE 示例 ----------------
export const deleteGoodsApi = createDeleteApi('/api/goods/delete')

页面业务调用示例

js
import {
  getSystemInfoApi,
  getTableListApi,
  getStreamDataApi,
  postLogoutApi,
  saveGoodsApi,
  editGoodsApi,
  deleteGoodsApi
} from '@/api/demo'

// 1. GET 无参
const loadInfo = async () => {
  const res = await getSystemInfoApi()
  console.log('系统信息', res)
}

// 2. GET 带参数(并发多次调用自动防重复)
const loadTable = async () => {
  const params = { page: 1, pageSize: 10, name: '' }
  const res = await getTableListApi(params)
  console.log('表格数据', res)
}

// 3. GET 关闭防重复接口(长轮询)
const pollData = async () => {
  const res = await getStreamDataApi({ time: Date.now() })
}

// 4. POST 无参
const logout = async () => {
  await postLogoutApi()
}

// 5. POST 带参数
const saveGoods = async () => {
  await saveGoodsApi({ name: '测试商品', price: 99 })
}

// 6. PUT
const editGoods = async () => {
  await editGoodsApi({ id: 1, name: '修改名称' })
}

// 7. DELETE
const removeGoods = async () => {
  await deleteGoodsApi({ id: 1 })
}

// 8. 手动传递 signal(配合 useCrud 自动传入,这里是手动演示)
const cancelDemo = async () => {
  const controller = new AbortController()
  getTableListApi({ page: 1 }, { signal: controller.signal })
  // controller.abort() // 取消请求
}

底层 useFetch 原生调用示例(极少场景使用)

js
import { useFetch } from '@wyfex/iutils'

const customRequest = async () => {
  await useFetch({
    url: '/api/upload',
    method: 'POST',
    data: new FormData(),
    skipDeduplicate: true // 当前请求单独关闭防重复
  })
}

Token 过期自动刷新拓展方案(进阶常用)

js
// src/utils/refreshToken.ts
import { setFetchGlobalConfig } from '@wyfex/iutils/fetchRequest'
import { refreshTokenApi } from '@/api/user'
import { useUserStore } from '@/stores/user'

export const refreshToken = async () => {
  const userStore = useUserStore()
  const res = await refreshTokenApi()
  const newToken = res.token
  userStore.setToken(newToken)
  // 更新全局请求头
  setFetchGlobalConfig({
    baseHeaders: { token: newToken }
  })
  return newToken
}

接口调用演示(业务页面,无需重复传递 token、错误处理)

js
import { getTableListApi, saveGoodsApi } from '@/api/demo'

// 查询列表,自动携带全局token,异常自动弹出消息框
const loadData = async () => {
  try {
    const data = await getTableListApi({ page: 1, pageSize: 10 })
    console.log(data)
  } catch (e) {
    // 可选:如果当前接口需要单独处理特殊逻辑,可以在这里捕获
    // 不捕获则统一交给全局globalErrorHandler处理
  }
}

// 提交表单
const submit = async () => {
  await saveGoodsApi({ name: '测试商品' })
}

单接口独立覆盖错误处理(局部优先级 > 全局)

极少数接口不想走全局错误弹窗,可以手动传入自定义 errorHandle

js
import { useFetch } from '@wyfex/iutils/fetchRequest'

const customReq = async () => {
  await useFetch(
    {
      url: '/api/xxx',
      method: 'GET'
    },
    // 单次请求独立错误回调,优先执行,覆盖全局
    (err) => {
      console.log('当前接口单独处理错误,不弹出message', err)
    }
  )
}

基于 MIT 许可发布