Nuxt3 请求知识点
三种方式
$fetch
useAsyncData
useFetch
$fetch
- $fetch 没有任何的缓存
使用场景
- setup 顶部
CAUTION
$fetch 顶部使用的时候没有任何缓存,会向服务器发送两次请求,一次是服务器端,一次是客户端
- 事件
CAUTION
$fetch 只发送一次请求,不用渲染
封装
- 在 composables 文件夹下面 新建一个 use$fetch.ts 文件
ts
interface RequestOptions {
[key: string]: any;
}
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";
// 请求拦截器
function handleRequest(options: RequestOptions) {
options.headers = {
...options.headers,
"Content-Type": "application/json",
token: unref(useCookie("token")),
sign: "123987",
};
}
// 响应拦截器
function handleResponse(response: any) {
if (response.error) {
throw new Error(response.error.message || "响应错误");
}
return response;
}
/**
* 创建请求方法
* @param method
*/
function createDollarFetchRequest(method: HttpMethod) {
return async function (
url: string,
data?: any,
options: RequestOptions = {}
) {
const {
public: { baseURL },
} = useRuntimeConfig();
const requestUrl = baseURL + url;
try {
handleRequest(options);
if (method == "GET") {
const response = await $fetch(requestUrl, {
method,
query: data,
key: JSON.stringify(Math.random() * 100),
...options,
onRequest() {
console.log("GET拦截器");
},
});
return handleResponse(response);
} else {
const response = await $fetch(requestUrl, {
method,
body: data,
...options,
onRequest() {
console.log("POST拦截器");
},
});
return handleResponse(response);
}
} catch (error) {
console.error("请求错误:", error);
throw error;
}
};
}
// 提供 $fetch & HTTP 方法 - 统一管理请求 - 再到组件中使用
export const useDollarGet = createDollarFetchRequest("GET");
export const useDollarPost = createDollarFetchRequest("POST");
export const useDollarPut = createDollarFetchRequest("PUT");
export const useDollarDelete = createDollarFetchRequest("DELETE");
使用
ts
import { useDollarGet, useDollarPost } from "~/composables/use$fetch";
const get1 = (params: any) => {
console.log(params);
return useDollarGet("/get1", params, { pick: ["data"] });
};
const post1 = (params: any) => {
return useDollarPost("/testrouter1", params, { pick: ["data"] });
};
export default {
get1,
post1,
};
组件里面用
ts
// ApiALL 就是上面那个文件 通过import * as ApiAll from "~/composables/use$fetch";引入
let postmessage2 = ref("");
const result1 = await ApiAll.get1({ id: "呵呵呵" }).catch((e) => {
navigateTo("/404");
});
postmessage2.value = result1.data;
useAsyncData
有缓存机制,当你的参数不变,路径不变,请求的时候只发送一次
使用场景
一般用于页面一开始获取数据,useAsyncData 与$fetch 一起使用,适用于多个接口
使用
- 组件里面
ts
const { data } = await useAsyncData("/api/getdata2", async () => {
const result = await Promise.all([
ApiAll.get1({ id: "呵呵呵4232" }),
ApiAll.post1({
id: "Post数据6999",
}),
]).catch((e) => {
return {
code: 500,
message: e.toString(),
};
});
if (result.code == 500) {
// 异常处理
return result;
} else {
// 正确返回值
return {
getdata: result[0].data,
postdata: result[1],
};
}
});
// 这里一定要判断下data 的值
if (!unref(data).getdata) {
navigateTo("/404");
}
- 这样请求后 你是看不到发送的请求的,因为他有缓存,他少发一次请求,客户端不在发送
如果你非要看见请求
- 只有每次清空缓存
ts
clearNuxtData(); // 加上他 清除缓存走了2次
const { data } = await useAsyncData("/api/getdata2", async () => {
const result = await Promise.all([
ApiAll.get1({ id: "呵呵呵4232" }),
ApiAll.post1({
id: "Post数据6999",
}),
]).catch((e) => {
return {
code: 500,
message: e.toString(),
};
});
console.log(result);
if (result.code == 500) {
// 异常处理
return result;
} else {
// 正确返回值
return {
getdata: result[0].data,
postdata: result[1],
};
}
});
// 这里一定要判断下data 的值
if (!unref(data).getdata) {
navigateTo("/404");
}
useFetch
有缓存机制,并且他给封装好数据.动态监听(这点最恶心)
比如一个输入框,当你不停的输入的时候,他会自己不停的发送请求,并且你看到请求的参数一直在变
个人不推荐.一般用$fetch
使用场景
一般用于事件触发
使用
- 封装 useFetch
ts
/*
* @Author: jsopy
* @Date: 2024-10-18 06:48:36
* @LastEditTime: 2024-10-18 13:30:18
* @FilePath: /demo1/composables/useFectchRequest.ts
* @Description:
*
*/
import type { UseFetchOptions } from "nuxt/app";
type HttpMethod = "GET" | "POST" | "PUT" | "DELETE";
type HandleRequestOptions = { request: Request; options: UseFetchOptions<any> };
type HandleResponseOptions = { response: any };
// 请求拦截器
function handleRequest({ options }: HandleRequestOptions) {
options.headers = {
...options.headers,
"Content-Type": "application/json",
token: unref(useCookie("token")),
sign: "6666",
};
}
// 响应拦截器
function handleResponse({ response }: HandleResponseOptions) {
if (response._data.error) {
throw new Error(response._data.error.message || "响应错误");
}
return response._data;
}
/**
* 创建请求方法
* @param method
*/
function createUseFetchRequest(method: HttpMethod) {
return async function (
url: string,
data?: any,
options: UseFetchOptions<any> = {}
) {
const {
public: { baseURL },
} = useRuntimeConfig();
const requestUrl = baseURL + url;
if (method == "GET") {
return await useFetch(requestUrl, {
...options,
method,
query: data,
onRequest: handleRequest,
onResponse: handleResponse,
});
} else {
return await useFetch(requestUrl, {
...options,
method,
body: data,
onRequest: handleRequest,
onResponse: handleResponse,
});
}
};
}
// 提供 useFetch & HTTP 方法 - 统一管理请求 - 再到组件中使用
export const useFetchGet = createUseFetchRequest("GET");
export const useFetchPost = createUseFetchRequest("POST");
export const useFetchPut = createUseFetchRequest("PUT");
export const useFetchDelete = createUseFetchRequest("DELETE");
- 剩下的步骤和前面封装的$fetch 一样使用