最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
如何在 setup 中优雅地调用 API:组合式函数封装异步请求的干货教程
时间:2026-06-07 10:21:46 编辑:袖梨 来源:一聚教程网
Vue 3 中调用 API 的核心是使用组合式函数封装请求逻辑,聚焦发起请求、处理响应、暴露 execute 接口,返回 { data, error, loading, execute },支持手动触发、错误加载状态响应式绑定及进阶能力如参数化、取消、缓存与防抖。
在 Vue 3 的 setup 中调用 API,核心不是“怎么发请求”,而是“如何组织得清晰、可复用、易测试、不污染组件逻辑”。直接在 setup 里写 axios.get() 看似快,但很快会陷入重复处理 loading、error、缓存、取消请求的泥潭。真正的优雅,来自组合式函数(Composable)的合理封装。
明确职责:组合式函数只管“请求逻辑”,不管“UI 状态”
一个高质量的 API 组合式函数,应聚焦三件事:发起请求、处理响应结构、暴露可控的执行接口。它不该直接修改组件内的 ref,也不该主动触发 UI 更新。
- 返回值推荐解构对象:
{ data, error, loading, execute },语义清晰,按需使用 -
execute是函数,而非自动执行——让调用方决定何时拉数据(比如点击后、路由就绪后) - 错误和加载状态用
ref包裹,方便在模板中响应式绑定(v-if="loading")
基础封装:带 loading 和 error 处理的通用模式
以下是一个生产可用的最小可行封装(以 axios 为例):
import { ref, Ref } from 'vue'import axios from 'axios'interface UseApiOptions { manual?: boolean // 是否手动触发,默认 false(自动执行)}export function useApi<T>(url: string, options: UseApiOptions = {}) { const data = ref<T | null>(null) const error = ref<Error | null>(null) const loading = ref(false) const execute = async () => { loading.value = true error.value = null try { const res = await axios.get<T>(url) data.value = res.data return res.data } catch (e) { error.value = e as Error throw e } finally { loading.value = false } } if (!options.manual) { execute() } return { data, error, loading, execute }}
在组件中使用时干净利落:
import { useApi } from '@/composables/useApi'export default defineComponent({ setup() { const { data, loading, error, execute } = useApi<User>('/api/user/1') const handleRefresh = () => execute() return () => ( <div> {loading.value ? '加载中...' : null} {error.value ? `错误:${error.value.message}` : null} {data.value ? <h2>{data.value.name}</h2> : null} <button onClick={handleRefresh}>刷新</button> </div> ) }})
进阶技巧:支持参数、取消请求、缓存与防抖
真实业务中,你很快会需要这些能力。它们不该堆在组件里,而应沉淀到组合式函数中:
-
动态参数:把
url改为函数,如(id: string) => `/api/user/${id}`,execute接收参数并重置状态 -
请求取消:用
AxiosController或AbortController,在execute中生成新 controller,并在下一次调用前 abort 上次(尤其适合搜索输入框) -
简单内存缓存:用 Map 缓存
url + JSON.stringify(params)对应的结果,命中则直接 resolve,避免重复请求 -
节流/防抖:对高频触发的
execute(如搜索),用lodash.debounce包一层,返回新的防抖函数
避坑提醒:别让组合式函数变成“黑盒”
封装是为了简化,不是隐藏复杂度。几个常见反模式要警惕:
- 把所有 API 请求都塞进一个叫
useRequest的万能函数里——参数越来越多,类型难推导,维护成本飙升 - 在组合式函数里直接调用
notification.success()或router.push()—— 违反关注点分离,组件失去控制权 - 不暴露原始响应(如
res.headers、res.status),导致分页、鉴权头等场景无法处理 - 忽略 TypeScript 类型推导,用
any或unknown敷衍,失去类型安全优势
好的组合式函数,应该像乐高积木:单个功能纯粹,拼起来却能构建复杂应用。它不替你做决定,只给你稳当的把手。
相关文章
- 无人商店运营模式解析 - 2026年智能零售新趋势 06-13
- 大猪蹄子是什么意思 - 网络流行语解析 06-13
- 开着美颜看《咒怨》-2026最新观影体验 06-13
- 花千骨电视剧全集在线观看 - 2026高清完整版 06-13
- skr是什么梗 - 2026最新网络流行语解析 06-13
- 病毒性营销策略解析 - 2026年高效传播方法 06-13