3.vueuse-createFetch实现接口请求及其封装(代替axios)

文章介绍了如何使用vueuse库中的createFetch函数封装网络请求,包括设置baseUrl、错误处理和请求拦截等功能,以替代axios。通过创建Fetch类并定义get、post等方法,简化了接口调用。同时,文章展示了如何配置全局请求头、错误处理和接口预设,以及使用useHandleApiRes优化响应数据处理。
摘要由CSDN通过智能技术生成

useFetch函数提供了中止请求、在请求发送前拦截请求、在url变化时自动重新获取请求等一系列很不错的api。
createFetch函数返回一个useFetch函数,该函数可以预先配置一些选项选项。这对于在整个项目中使用相同URL(即baseURL)或需要授权头的API进行交互以及API统一错误处理等是非常有用的。
关于useFetchcreateFetch的使用示例及api参数请查看官方文档

以下是在具体项目中对createFetch的使用方式如下:

  1. 封装Fetch
// 1. fetch.ts
import { createFetch, CreateFetchOptions, UseFetchOptions } from '@vueuse/core';
import { objectToSearch } from '@/utils';

import type { IFeatchParams } from './types';

class Fetch {
  instances;
  constructor(params: CreateFetchOptions) {
    const {
      baseUrl,
      combination = 'chain',
      fetchOptions = {
        mode: 'cors',
      },
      options,
    } = params;
    this.instances = createFetch({
      baseUrl,
      combination,
      options,
      fetchOptions,
    });
  }
  get(
    { url, params = {} }: Omit<IFeatchParams, 'data'>,
    featOptions: UseFetchOptions = {}
  ) {
    return this.instances(
      `${url}${objectToSearch(params) ? `?${objectToSearch(params)}` : ''}`,
      featOptions
    ).json();
  }
  post(
    { url, data, params = {} }: IFeatchParams,
    featOptions: UseFetchOptions = {}
  ) {
    return this.instances(
      `${url}${objectToSearch(params) ? `?${objectToSearch(params)}` : ''}`,
      featOptions
    )
      .post(data)
      .json();
  }
  put(
    { url, data, params = {} }: IFeatchParams,
    featOptions: UseFetchOptions = {}
  ) {
    return this.instances(
      `${url}${objectToSearch(params) ? `?${objectToSearch(params)}` : ''}`,
      featOptions
    )
      .put(data)
      .json();
  }
  patch(
    { url, data, params = {} }: IFeatchParams,
    featOptions: UseFetchOptions = {}
  ) {
    return this.instances(
      `${url}${objectToSearch(params) ? `?${objectToSearch(params)}` : ''}`,
      featOptions
    )
      .patch(data)
      .json();
  }
  delete(
    { url, params = {} }: IFeatchParams,
    featOptions: UseFetchOptions = {}
  ) {
    return this.instances(
      `${url}${objectToSearch(params) ? `?${objectToSearch(params)}` : ''}`,
      featOptions
    )
      .delete()
      .json();
  }
}

export default Fetch;

因为get请求的参数是直接拼接在url上(或许是我还没弄明白怎么像axios一样传参…),需要手动进行拼接,objectToSearch函数如下

// utils/objectToSearch.ts
export function objectToSearch(params: Record<string, any>) {
  let searchParams = '';
  if (Object.keys(params).length > 0) {
    for (const key in params) {
      searchParams += `${key}=${params[key]}&`;
    }
    searchParams = searchParams.slice(0, searchParams.length - 1);
  }
  return searchParams;
}
  1. 配置所有接口预设及请求头token、错误处理等
import { useLocalCache } from '@/hooks';
import Fetch from './fetch';

const { getCache, clearCache } = useLocalCache();
const whiteApis = ['/login']; // 接口白名单

export const Request = new Fetch({
  baseUrl: import.meta.env.VITE_BASE_URL, // 这里的环境为vite,环境变量可自定义。当然也可以直接使用定值,例 '/api'
  options: {
    beforeFetch({ options, cancel, url }) {
      const token = getCache('token');
      if (!whiteApis.find((item) => url.includes(item)) && !token) {
        cancel(); // 取消请求(不发送请求)
      }
      options.headers = {
        ...options.headers,
        Authorization: token,
      };
      return { options };
    },
    afterFetch(ctx) {
      // 这里做统一错误处理
      const { code, message } = ctx.data;
      if (code === 102) {
        console.log('登录过期,请重新登录');
        clearCache();
        location.reload();
      } else if (code !== 0) {
        console.log(message || '请求失败,请稍后再试');
      }
      return ctx;
    },
    onFetchError(ctx) {
      // 错误请求
      console.log('错误的请求,请稍后再试');
      return ctx;
    },
    timeout: 10000,
  },
});

上面引入的useLocalCache1. vueuse-useLocalStorage在项目中的使用

  1. 使用示例
import { Request } from '@/service';
interface ILogin {
  password: string;
  username: string;
}
export function Login(data: ILogin) {
  return Request.post({
    url: 'login',
    data,
  });
}
// 1. 使用(中止请求)
const { abort, data } = Login({ password: 'admin123', username: 'sy' })
abort() // 中止请求,同 execute
console.log(data.value) // undefined
// 2. 使用
Login({ password: 'admin123', username: 'sy' }).then((res) => {
  const { code, data } = res.data.value;
  if (code === 0) {
    console.log('data', data);
  }
});
  1. 优化请求
export function useHandleApiRes<T = any>(promise: PromiseLike<any>) {
  return promise.then((res) => {
    const { data } = res;
    const { code, message, data: resData } = unref(data) || {};
    return {
      code,
      message,
      data: resData as T,
    };
  });
}

// 示例
interface ILoginRes {
  username: string;
  avatar: string;
}
const submit = async () => {
  const { code, data, message } = await useHandleApiRes<ILoginRes>(
    Login({ password: 'admin1234', username: 'sy' })
  );
  if (code === 0) {
    console.log('data', data);
  } else {
    console.log(message);
  };

useFetch/createFetch的使用及封装,相对axios来说更灵活简单些,配置起来也不会太麻烦。且项目中用到vueuse之后可以少安装很多npm包了。用起来还是很香的~

项目在线地址github

vueuse相关系列文章

1.vueuse-useLocalStorage在项目中的使用

2.vueuse-useCssVar实现主题色切换功能

3.vueuse-createFetch实现接口请求及其封装(代替axios)

4.vueuse-useFullscreen优雅的使用全屏及退出全屏

5.vueuse-useDark实现暗黑主题及浅亮主题及Element-Plus暗黑模式

  • 3
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值