第 103 期 - VueUse useFetch 功能与实现解析
logoFRONTALK AI/2月5日 16:34/阅读原文

摘要

文章主要介绍了 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) }

(二)添加默认请求类型

  1. 给请求添加默认是GET的请求,配置对象const config = { method: 'GET' },然后函数变为return fetch(url, { method: config.method,...options })
  2. 对于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;
    })
};

(三)函数返回值优化

  1. 为了让函数返回值更符合习惯(直接返回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);
    }
};
  1. 探讨了返回带有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);
    }
};

(五)性能优化与更多返回值

  1. const data = ref(null)换成shallowRef提升性能,并添加response对象到返回值以便特殊处理。
  2. 对异常信息也进行响应式处理,添加error到返回值。
  3. 添加请求的状态响应isFetchingisFinished,用于判断请求是否正在发送或者已经发送完成。

(六)函数封装与逻辑优化

  1. isFetchingisFinished的赋值操作封装成一个loading函数。
  2. 添加配置项refetch,当为true时,url值改变自动重新发送请求,使用toRef防止refetchurl不是响应式变量。
  3. 在执行execute时候用了Promise,如Promise.resolve().then(() => execute()),这在实现设置getpost等方法的时候会用到。

(七)添加钩子函数

  1. 添加各个阶段的钩子:请求成功、请求失败、请求完成,使用createEventHook函数来创建钩子。
  2. 使用发布订阅模式优化钩子函数的实现。
  3. 补充请求之前的钩子,在execute函数中通过if (options.beforeFetch)来处理请求之前的操作。

(八)取消请求与超时设置

  1. 实现取消请求功能,使用AbortController来中止fetch请求。在useFetch函数中添加相关逻辑,如判断是否支持AbortController,设置canAbortaborted等变量,实现abort函数。
  2. 基于取消请求实现设置请求超时时间,添加timer变量,在execute函数中通过if (options.timeout)设置定时器,超时则调用abort函数。

(九)设置请求方法与返回内容格式

  1. 添加设置GETPOSTPUT等方法的函数,通过setMethod函数设置请求方法,在shell对象中添加各种请求方法的调用。
  2. 设置请求返回内容的格式,通过setType函数设置不同的返回类型,如jsontextblob等。
 

扩展阅读

Made by 捣鼓键盘的小麦 / © 2025 Front Talk 版权所有