这些函数只能用在 setup or Lifecycle Hooks 中。
server与client都会发送网络请求(有重复发送缺点,建议使用nuxt提供的hook)
// 1.使用 $fetch 来发起网络请求
// server and client
$fetch(BASE_URL + "/homeInfo", {
method: "GET",
}).then((res) => {
console.log(res);
});
useAsyncData(url, () => $fetch(url))
在刷新页面时, 可以减少客户端发起的一次请求,服务端会发起请求
切换路由客户端会发起网络请求,服务端不会
会阻塞导航
<script setup>
const { data } = await useAsyncData('count', () => $fetch('/api/count'))
</script>
useFetch接收URL并获取数据,而useAsyncData可能有更复杂的逻辑。
useFetch(url)几乎等同于useAsyncData(url, () => $fetch(url))
<script setup>
const { data: count } = await useFetch('/api/count')
</script>
文档
function useFetch(
url: string | Request | Ref<string | Request> | () => string | Request,
options?: UseFetchOptions<DataT>
): Promise<AsyncData<DataT>>
type UseFetchOptions = {
key?: string
method?: string
query?: SearchParams
params?: SearchParams
body?: RequestInit['body'] | Record<string, any>
headers?: { key: string, value: string }[]
baseURL?: string
server?: boolean
lazy?: boolean
immediate?: boolean
default?: () => DataT
transform?: (input: DataT) => DataT
pick?: string[]
watch?: WatchSource[]
}
type AsyncData<DataT> = {
data: Ref<DataT>
pending: Ref<boolean>
refresh: (opts?: { dedupe?: boolean }) => Promise<void>
execute: () => Promise<void>
error: Ref<Error | boolean>
}
refresh刷新,与响应式参数改变再次请求
<script setup lang="ts">
const count = ref(1);
// 1.点击刷新时, 是在server端发起网络请求, 客户端不会发起网络请求,水合之后客户端是可以当前数据
const { data, refresh, pending } = await useFetch<IResultData>(
BASE_URL + "/goods",
{
method: "POST",
body: {
count,
},
}
);
function refreshPage() {
count.value++; // 会自动从新发起网络请求
// refresh(); // client 刷新请求
}
</script>
使用拦截器
const { data, pending, error, refresh } = await useFetch('/api/auth/login', {
onRequest({ request, options }) {
// Set the request headers
options.headers = options.headers || {}
options.headers.authorization = '...'
},
onRequestError({ request, options, error }) {
// Handle the request errors
},
onResponse({ request, response, options }) {
// Process the response data
return response._data
},
onResponseError({ request, response, options }) {
// Handle the response errors
}
})
官方文档
useLazyFetch 为useFetch提供了一个包装器,通过将lazy选项设置为true,在处理程序解析之前触发导航。不会阻塞导航
使用watch确保一定可以拿到这个data的数据
<template>
<div v-if="pending">
Loading ...
</div>
<div v-else>
<div v-for="post in posts">
<!-- do something -->
</div>
</div>
</template>
<script setup>
/* Navigation will occur before fetching is complete.
Handle pending and error states directly within your component's template
*/
const { pending, data: posts } = useLazyFetch('/api/posts')
watch(posts, (newPosts) => {
// Because posts starts out null, you won't have access
// to its contents immediately, but you can watch it.
})
</script>
useLazyAsyncData为useAsyncData提供了一个包装器,通过将lazy选项设置为true,在处理程序解析之前触发导航。
官方文档
获取数据Nuxt推荐使用 useFetch 函数,为什么不是 axios ?
import type { AsyncData, UseFetchOptions } from "nuxt/dist/app/composables";
const BASE_URL = "http://codercba.com:9060/juanpi/api/";
type Methods = "GET" | "POST";
export interface IResultData<T> {
code: number;
data: T;
}
class HYRequest {
request<T = any>(
url: string,
method: Methods,
data?: any,
options?: UseFetchOptions<T>
): Promise<AsyncData<T, Error>> {
return new Promise((resolve, reject) => {
const newOptions: UseFetchOptions<T> = {
baseURL: BASE_URL,
method: method,
...options,
};
if (method === "GET") {
newOptions.query = data; // query -> params
}
if (method === "POST") {
newOptions.body = data;
}
useFetch<T>(url, newOptions as any)
.then((res) => {
// res => { data:T, pending, refresh, error ... } => AsyncData
resolve(res as AsyncData<T, Error>);
})
.catch((error) => {
reject(error);
});
});
}
get<T = any>(url: string, params?: any, options?: UseFetchOptions<T>) {
return this.request(url, "GET", params, options);
}
post<T = any>(url: string, data?: any, options?: UseFetchOptions<T>) {
return this.request(url, "POST", data, options);
}
}
export default new HYRequest();
实例
创建一个新文件server/api/homeInfo.ts:
export default defineEventHandler((event) => {
let { req, res } = event.node;
console.log(req.method);
console.log(req.url);
return {
code: 200,
data: {
name: "liujun",
age: 18,
},
};
});
你现在可以使用await $fetch(‘/api/homeInfo’)通用地调用这个API。
官方文档server