watcheffect 可自动触发 api 请求,依赖响应式变量变化;需在回调中直接使用 ref 或 reactive 数据,支持 abortcontroller 防竞态,并可封装为 useapi 组合式函数统一管理请求、loading 与错误。

watchEffect 可以在响应式数据变化时自动触发 API 请求,无需手动监听或写一堆 watch 逻辑。关键在于把依赖的数据直接写进回调函数里,Vue 会自动追踪并响应变化。
让 API 请求随响应式变量自动执行
只要在 watchEffect 的回调中使用了某个响应式变量(比如 ref 或 reactive 的属性),它就会成为依赖项。变量一变,请求立刻重发。
例如:
const keyword = ref('')
const list = ref([])
watchEffect(async () => {
if (!keyword.value.trim()) return
const res = await fetch(`/api/search?q=${keyword.value}`)
list.value = await res.json()
})
这里 keyword.value 是响应式依赖,输入框一改,请求就自动发出去——不用 watch、不用 onMounted 里手动调一次,也不用额外写防抖(可后续加)。
控制执行时机:跳过首次或添加条件
默认会在定义时立即执行一次。如果只想在变化后才请求(比如避免空搜索),加个判断即可;若需完全跳过初始执行,可用 lazy: true 选项(但注意这会让它变成纯“监听”,不主动触发)。
- 推荐做法:在回调里加业务判断,如
if (!keyword.value) return - 慎用 lazy:开启后需手动调一次,否则第一次永远不发请求
- 想首次也请求?什么都不加,默认行为就满足
避免重复请求和竞态问题
用户快速输入时,可能发出多个请求,旧请求返回后覆盖新结果。简单方案是用 AbortController 主动取消前序请求:
let controller
watchEffect(async () => {
controller?.abort()
controller = new AbortController()
try {
const res = await fetch(`/api/search?q=${keyword.value}`, {
signal: controller.signal
})
list.value = await res.json()
} catch (e) {
if (e.name !== 'AbortError') console.error(e)
}
})
封装成可复用的请求钩子(useApi)
把上面逻辑抽成组合式函数,以后任何页面都能一键接入:
function useApi(urlFn, options = {}) {
const data = ref(null)
const loading = ref(false)
const error = ref(null)
watchEffect(async (onInvalidate) => {
const url = urlFn()
if (!url) return
loading.value = true
error.value = null
const controller = new AbortController()
onInvalidate(() => controller.abort())
try {
const res = await fetch(url, { signal: controller.signal })
data.value = await res.json()
} catch (e) {
if (e.name !== 'AbortError') error.value = e
} finally {
loading.value = false
}
})
return { data, loading, error }
}
// 使用
const { data, loading } = useApi(() => `/api/user/${id.value}`)
这样就把请求逻辑、loading、错误、取消全收拢了,组件里只管用,不操心细节。
大量免费API接口:立即使用
涵盖生活服务API、金融科技API、企业工商API、等相关的API接口服务。免费API接口可安全、合规地连接上下游,为数据API应用能力赋能!










