第 103 期 - VueUse useFetch 功能与实现解析
摘要
文章主要介绍了 VueUse 中 useFetch 函数的功能,包括请求发送、响应处理、状态管理、钩子函数、取消请求、超时设置以及各种请求方法和返回内容格式的设置等,逐步展示了 useFetch 函数的实现过程。
一、useFetch 的基本功能介绍
文章开篇提到useFetch
通过Fetch API
方式发送请求,并具备一些特殊功能,如在触发请求之前拦截请求、在url
更改时自动重新获取请求以及使用预定义选项创建自己的请求封装。
二、useFetch 的使用示例
(一)基础引入
示例代码import { useFetch } from '@vueuse/core'
,const { isFetching, error, data } = useFetch(url)
展示了useFetch
的基础使用方式。
三、useFetch 的源码解析
(一)简单的 Fetch API 封装
最初的useFetch
函数简单封装了fetch
,如export function useFetch(url, options) { return fetch(url, options) }
。
(二)添加默认请求类型
- 给请求添加默认是
GET
的请求,配置对象const config = { method: 'GET' }
,然后函数变为return fetch(url, { method: config.method,...options })
。 - 对于
Fetch
获取response body
,默认以文本形式获取,在配置对象中添加type: 'text'
,并在函数中处理response
数据。例如:
const data = ref(null);
return {
data,
fetch: fetch(url, { method: config.method,...options }).then(async (response) => {
const responseData = await response[config.type]();
data.value = responseData;
return responseData;
})
};
(三)函数返回值优化
- 为了让函数返回值更符合习惯(直接返回
Promise
),给返回值模拟一个then
方法。
const promise = fetch(url, { method: config.method,...options }).then(async (response) => {
const responseData = await response[config.type]();
data.value = responseData;
return responseData;
});
return {
data,
then(onFullfilled, onRejected) {
return promise.then(onFullfilled, onRejected);
}
};
- 探讨了返回带有
then
方法的对象能否使用await
,分析了await
后面可接的类型(Promise
实例、普通对象、Thenable
对象),得出这里返回带有then
方法的对象,await
可以像处理Promise
一样处理。
(四)控制请求发送时机
添加配置项immediate
来控制是否马上发送请求,代码如下:
let promise;
const execute = async () => {
return fetch(url, { method: config.method,...options }).then(async (response) => {
const responseData = await response[config.type]();
data.value = responseData;
return responseData;
});
};
if (options.immediate) {
promise = execute();
}
return {
data,
execute,
then(onFullfilled, onRejected) {
return promise? promise.then(onFullfilled, onRejected) : Promise.resolve().then(onFullfilled, onRejected);
}
};
(五)性能优化与更多返回值
- 将
const data = ref(null)
换成shallowRef
提升性能,并添加response
对象到返回值以便特殊处理。 - 对异常信息也进行响应式处理,添加
error
到返回值。 - 添加请求的状态响应
isFetching
和isFinished
,用于判断请求是否正在发送或者已经发送完成。
(六)函数封装与逻辑优化
- 将
isFetching
和isFinished
的赋值操作封装成一个loading
函数。 - 添加配置项
refetch
,当为true
时,url
值改变自动重新发送请求,使用toRef
防止refetch
和url
不是响应式变量。 - 在执行
execute
时候用了Promise
,如Promise.resolve().then(() => execute())
,这在实现设置get
、post
等方法的时候会用到。
(七)添加钩子函数
- 添加各个阶段的钩子:请求成功、请求失败、请求完成,使用
createEventHook
函数来创建钩子。 - 使用发布订阅模式优化钩子函数的实现。
- 补充请求之前的钩子,在
execute
函数中通过if (options.beforeFetch)
来处理请求之前的操作。
(八)取消请求与超时设置
- 实现取消请求功能,使用
AbortController
来中止fetch
请求。在useFetch
函数中添加相关逻辑,如判断是否支持AbortController
,设置canAbort
、aborted
等变量,实现abort
函数。 - 基于取消请求实现设置请求超时时间,添加
timer
变量,在execute
函数中通过if (options.timeout)
设置定时器,超时则调用abort
函数。
(九)设置请求方法与返回内容格式
- 添加设置
GET
、POST
、PUT
等方法的函数,通过setMethod
函数设置请求方法,在shell
对象中添加各种请求方法的调用。 - 设置请求返回内容的格式,通过
setType
函数设置不同的返回类型,如json
、text
、blob
等。
扩展阅读
Made by 捣鼓键盘的小麦 / © 2025 Front Talk 版权所有