1. useFetch
    2. useLazyFetch
    3. useAsyncData
    4. useLazyAsyncData
    5. 数据转换
    6. 数据刷新
    7. refreshNuxtData
    8. clearNuxtData
    9. 直接使用$fetch

Nuxt内置4个函数来处理数据:useFetch,useLazyFetch, useAsyncData, useLazyAsyncData。这些函数都只能在setup代码块或者Vue生命周期函数中使用。

useFetch

在Nuxt的页面、组件和插件中,无论客户端还是服务端,都可以使用useFetch调用接口获取数据。

useFetch是对useAsyncData$fetch的封装。

示例:

<script setup>
const { data: count } = await useFetch('/api/count')
</script>

<template>
  Page visits: {{ count }}
</template>

useLazyFetch

这个组合式函数等同于使用useFetch时带上lzey: true参数。也就是说,函数是异步的,不会阻塞页面跳转。这意味着你需要处理数据初始时默认为null的情况,如下示例:

<template>
  <!-- you will need to handle a loading state -->
  <div v-if="pending">
    Loading ...
  </div>
  <div v-else>
    <div v-for="post in posts">
      <!-- do something -->
    </div>
  </div>
</template>

<script setup>
const { pending, data: posts } = useLazyFetch('/api/posts')
watch(posts, (newPosts) => {
  // 因为posts初始值为null,你并不能马上在模板里使用它,但是你可以watch它的变化
})
</script>

useAsyncData

在页面、组件或者插件中,你可以通过useAsyncData获取需要异步处理的数据。

useAsyncData用来处理比较复杂的异步场景.useFetch则是useAsyncData的语法糖,大致等同于useAsyncData(url, () => $fetch(url))

示例: server/api/count.ts

let counter = 0
export default defineEventHandler(() => {
  counter++
  return counter
})

app.vue

<script setup>
const { data } = await useAsyncData('count', () => $fetch('/api/count'))
</script>

<template>
  Page visits: {{ data }}
</template>

useLazyAsyncData

等同于useAsyncData并使用lazy: true参数。

useLazyAsyncData不阻塞页面跳转,但是需要手动处理初始数据为null的情况(如同上面useLazyFetch)

示例:

<template>
  <div>
    {{ pending ? 'Loading' : count }}
  </div>
</template>

<script setup>
const { pending, data: count } = useLazyAsyncData('count', () => $fetch('/api/count'))
watch(count, (newCount) => {
  // Because count starts out null, you won't have access
  // to its contents immediately, but you can watch it.
})
</script>

数据转换

接口返回的数据,如果不符合前端需要的结构,可以用transform方法进行转换。我们推荐多使用transform来精简接口返回值,只保留在页面中能用到的数据,以提升页面性能。

示例:

<script setup>
const { data: users } = await useAsyncData(
  "users",
  () => $fetch('/api/users'),
  {
    transform: (users) =>
      users.map((user) => ({
        id: user.id,
        fullName: `${user.firstName} ${user.surname}`,
      })),
  }
);
</script>

<template>
  <div>
    <ul>
      <li v-for="user in users" :key="user.id">
        {{ user.fullName }}
      </li>
    </ul>
  </div>
</template>

数据刷新

useFetch返回的refresh方法,可以用来刷新数据(再次调用接口)

<script setup>
const page = ref(1)

const { data: users, pending, refresh, error } = await useFetch(() => `users?page=${page.value}&take=6`, { baseURL: config.API_BASE_URL }
)

function previous() {
  page.value--
  refresh()
}

function next() {
  page.value++
  refresh()
}
</script>

refreshNuxtData

清除useAsyncDatauseLazyAsyncDatauseFetchuseLazyFetch的缓存,然后再次调用接口。这个方法仅针对当前页面有效。

<template>
  <div>
    {{ pending ? 'Loading' : count }}
  </div>
  <button @click="refresh">Refresh</button>
</template>

<script setup>
const { pending, data: count } = useLazyAsyncData('count', () => $fetch('/api/count'))

const refresh = () => refreshNuxtData('count')
</script>

clearNuxtData

清除所有页面使用useAsyncDatauseFetch的缓存和pending状态。

直接使用$fetch

Nuxt在ofetch的基础上封装了全局方法$fetch,可以在Vue应用和API中使用。

在Vue组件中,我们推荐使用useFetch或者useAsyncData + $fetch,而不是直接使用$fetch。因为在组件中直接使用$fetch,容易造成两次接口调用(服务端一次,客户端一次)

示例:

<script setup>
// During SSR data is fetched twice, one on the server and one on the client.
const dataTwice = await $fetch("/api/item")

// During SSR data is fetched only on the server side and transferred to the client.
const { data } = await useAsyncData('item', () => $fetch('/api/item'))

// You can also useFetch as shortcut of useAsyncData + $fetch
const { data } = await useFetch('/api/item')
</script>