赞
踩
useFetch
函数提供了中止请求、在请求发送前拦截请求、在url变化时自动重新获取请求等一系列很不错的api。
createFetch
函数返回一个useFetch函数,该函数可以预先配置一些选项选项。这对于在整个项目中使用相同URL(即baseURL)或需要授权头的API进行交互以及API统一错误处理等是非常有用的。
关于useFetch
及createFetch
的使用示例及api参数请查看官方文档
以下是在具体项目中对createFetch的使用方式如下:
// 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;
}
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, }, });
上面引入的useLocalCache
见 1. vueuse-useLocalStorage在项目中的使用
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); } });
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包了。用起来还是很香的~
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。