当前位置:   article > 正文

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

createfetch

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;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80

因为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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  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,
  },
});
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

上面引入的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
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  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);
  };
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26

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暗黑模式

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/盐析白兔/article/detail/257302
推荐阅读
相关标签
  

闽ICP备14008679号