@ly-js/request
v0.1.0
Published
request of ly-js
Readme
@ly-js/request
基于 Vue 3 的轻量请求工具集,涵盖:
- 组合式请求
createRequest/useRequest(含重试、全屏 Loading、请求中断) - 业务基类
BaseService(CRUD、分页、批量删除、上传、参数序列化) - 错误模型
HttpError与isHttpError - 常量
HTTP_STATUS_MESSAGE
适配任意实现了 HttpInstance 接口的 HTTP 客户端(如 axios)。
安装
npm
npm i @ly-js/request --saveyarn
yarn add @ly-js/requestpnpm
pnpm add @ly-js/request快速上手(组合式请求)
import { createRequest, RequestState } from '@ly-js/request/use'
// 可选:提供全屏 Loading 的启停,供内部调用
const useRequest = createRequest({
fullLoadingConfig: {
start: opts => {
/* 打开全屏 Loading */
},
stop: () => {
/* 关闭全屏 Loading */
},
},
})
// 任意异步函数皆可:支持 Promise、[Promise, abort]、或带 abort 的 Promise(RequestPromise)
const fetchUser = async (id: number) => {
const res = await api.get(`/user/${id}`)
return res
}
const { data, loading, error, state, mutate, abort } = useRequest(fetchUser, {
immediate: false,
retry: 2,
retryDelay: 300,
retryStrategy: 'immediate', // or 'exponential'
beforeRequest: id => console.log('before', id),
afterRequest: res => res, // 可返回转换后的数据写入 data
success: d => console.log('success', d),
fail: e => console.warn('fail', e),
fullLoading: true, // 触发 fullLoadingConfig.start/stop
})
// 触发请求
await mutate(1)
// 中断进行中的请求
abort()
// 状态枚举
;RequestState.IDLE | PENDING | SUCCESS | FAILURE | ABORTEDUseRequestOptions
immediate: 是否初始化后立即触发一次请求initialData:data的初始值retry/retryDelay/retryStrategy: 自动重试配置beforeRequest(...args)/afterRequest(result)/success(data)/fail(err): 生命周期钩子fullLoading: 带参或布尔值,结合fullLoadingConfig使用
返回值
data: Ref<T | undefined>loading: Ref<boolean>error: Ref<any>state: Ref<RequestState>mutate(...args): Promise<T | undefined>abort(): void
UseHelper 快速构造 use* Hook
import { UseHelper } from '@ly-js/request/use'
// 初始化内部 useRequest(只需一次)
UseHelper.createUseSWR({})
// 将任意函数包装为 use Hook,并支持默认参数来源(argsSource)
const useAdd = UseHelper.createUse(async (a: number, b: number) => a + b)
// 1) 无默认参数:直接透传 mutate 入参
useAdd().mutate(1, 2)
// 2) 提供默认参数:数组/元组/函数/Ref/Computed 皆可;mutate 的入参按位置覆盖
const { mutate, data } = useAdd({}, () => [1, 2] as const)
await mutate() // 使用默认 [1,2]
await mutate(2) // 覆盖首参 -> [2,2]迁移提示:
UseHelper.createHooks已废弃(deprecated),不再文档化。
BaseService(业务基类)
BaseService<G, A = G, D = G, U = A, F = G, DF = G> 针对典型 REST 资源封装了常用能力:
import { BaseService } from '@ly-js/request/core'
class UserService extends BaseService<{ id: number; name: string }> {
pk = 'id'
constructor(http?: any) {
super('user', http)
}
}
// 设置全局 http 实例(可选)
BaseService.setHttp(http)
// 可选:设置上传实现
BaseService.setUpload(async (url, file, params, config, onProgress) => {
// 返回值需是 HttpResponse 结构(见类型定义)
return http.request({
url,
method: config?.method || 'post',
data: {
/* FormData */
},
onUploadProgress: onProgress,
})
})
const svc = new UserService()
await svc.list()
await svc.get({ id: 1 })
await svc.post({ id: 0, name: 'a' })
await svc.put({ id: 1, name: 'b' })
await svc.delete({ id: 2 })
await svc.update({ id: 3, name: 'c' }) // 有 id 走 put,否则走 post
await svc.multipleDelete({ ids: [1, 2] })
await svc.clear({ all: true })
// 上传(优先走自定义 setUpload;否则浏览器环境回退到 webUpload)
await svc.upload('/upload', file, { biz: 1 }, { method: 'post' }, e => console.log(e.percent))方法清单
query(url, params?, config?, qsConfig?): GET +qs序列化list(params?, config?):/${module}列表,返回{ code, msg, data }paging(params, config?):/${module}分页get(params, config?):/${module}/:idpost(data, config?):/${module}put(params, config?):/${module}/:iddelete(params, config?):/${module}/:idmultipleDelete(params, config?, qsConfig?):/${module}批量删除,带序列化clear(params, config?, qsConfig?):/${module}/clearupdate(params, config?): 根据pk是否存在决定post或putupload(url, file|UploadParams, params?, config?, onProgress?): 自定义上传或webUpload
可覆写点
extractResponseData(response): 默认取response.dataserializer(params, qsConfig): 默认arrayFormat: 'repeat'
axios 集成与中断(abort)示例
import axios from 'axios'
import type { HttpInstance } from '@ly-js/request/core'
import { BaseService } from '@ly-js/request/core'
// 1) 创建 axios 实例
const instance = axios.create({ baseURL: '/api' })
// 2) 适配 HttpInstance,并实现 initAbortController 用于中断
const http: HttpInstance = {
request: config => instance.request(config).then(r => r.data),
get: (url, config) => instance.get(url, config).then(r => r.data),
delete: (url, config) => instance.delete(url, config).then(r => r.data),
head: (url, config) => instance.head(url, config).then(r => r.data),
options: (url, config) => instance.options(url, config).then(r => r.data),
post: (url, data, config) => instance.post(url, data, config).then(r => r.data),
put: (url, data, config) => instance.put(url, data, config).then(r => r.data),
patch: (url, data, config) => instance.patch(url, data, config).then(r => r.data),
initAbortController: (_url, config) => {
const controller = new AbortController()
;(config as any).signal = controller.signal
return () => controller.abort('abort by user')
},
}
// 3) 注入至 BaseService(也可直接传入到具体 Service 实例构造函数)
BaseService.setHttp(http)
// 4) 可选:注入上传实现(使用 axios 原生 upload 事件)
BaseService.setUpload(async (url, file, params, config, onProgress) => {
const form = new FormData()
form.append('file', file as any)
if (params) Object.entries(params).forEach(([k, v]) => form.append(k, v as any))
return instance.request({
url,
method: (config?.method as any) || 'post',
data: form,
headers: { 'Content-Type': 'multipart/form-data' },
onUploadProgress: onProgress,
})
})错误处理
import { HttpError, isHttpError } from '@ly-js/request/core'
try {
await svc.get({ id: 404 })
} catch (e) {
if (isHttpError(e)) {
console.log(e.status, e.statusText, e.data)
}
}常量
import { HTTP_STATUS_MESSAGE } from '@ly-js/request/constants'
// 例如:HTTP_STATUS_MESSAGE[404] => '404: 资源不存在'包导出
@ly-js/request: 全量导出(constants/core/use)@ly-js/request/core: 核心能力(BaseService/HttpError/RequestPromise/types)@ly-js/request/use: 组合式请求(createRequest/UseHelper/RequestState)@ly-js/request/constants: 常量与类型
构建与外部依赖说明
- ESM/CJS 构建:仅将
vue、@ly-js/utils、qs声明为 external,打包时会保留为 import/require,由你的构建工具解析。 - IIFE 构建:仅将上述三者作为外部,其他依赖均已内联打包,产物为
dist/index.global.js,以lyRequest为全局变量名。 - 使用时确保提供这三者:
vue >= 3.5@ly-js/utilsqs
兼容性
- 需要
vue >= 3.5 - 默认使用浏览器或任意支持
AbortController的环境实现中断;在不支持的环境下,可忽略initAbortController,则abort()不会真正取消底层请求,但仍会切换状态并忽略结果
迁移与废弃
UseHelper.createHooks已废弃(deprecated),请迁移到UseHelper.createUse
