Nuxt 3 提供兩個 composables(useFetch
、useAsyncData
)和一個 utils($fetch
) 做為取得資料函式:
useFetch
最簡單最常用的函式$fetch
能根據使用者的行為發出請求useAsyncData
和 $fetch
一起使用,有更多的設定可以使用useFetch
用 useFetch
測試昨天寫的 API。
在 app.vue
加入以下程式碼。
// app.vue
<template>
<div>
<div v-for="item in list.data">
{{ item.key.replaceAll('todo:', '') }}
<input type="checkbox" v-model="item.value.isFinish" @change="Put(item)">
<button type="button" @click="Delete(item)">Delete</button>
</div>
</div>
<label for="todo">todo:</label>
<input type="text" id="todo" name="todo" v-model="todo" />
<button type="button" @click="Post">Submit</button>
</template>
<script setup lang="ts">
const todo = ref('')
const list = ref([])
list.value = await useFetch('/api/todo')
const Post = async () => {
await useFetch('/api/todo', {
method: 'post',
body: { name: todo.value }
})
list.value = await useFetch('/api/todo')
}
const Put = async (item) => {
await useFetch('/api/todo', {
method: 'put',
body: { name: item.key.replaceAll('todo:', ''), isFinish:item.value.isFinish }
})
list.value = await useFetch('/api/todo')
}
const Delete = async (item) => {
await useFetch('/api/todo', {
method: 'delete',
body: { name: item.key.replaceAll('todo:', '')}
})
list.value = await useFetch('/api/todo')
}
</script>
畫面顯示:
測試功能:
新增
修改
刪除
useFetch
有提供一些設定透過參數可以控制其行為。
預設情況下,useFetch
在使用 Vue Suspense 導覽至新頁面前會等待其非同步函式解析,如果使用 lazy
選項就會忽略此功能。
<template>
<div v-if="pending">
...
</div>
<div v-else>
<div v-for="item in list">
...
</div>
</div>
</template>
<script setup lang="ts">
const { pending, data: list } = useFetch('/api/todo', {
lazy: true
})
</script>
也可以使用 useLazyFetch
。
const { pending, data: list } = useLazyFetch('/api/todo')
預設情況下,useFetch
會在客戶端和伺服器環境上執行,將 server
設為 false
可以只在客戶端執行。
與 lazy
一起用對於第一次渲染時不需要的資料非常有用。
const { pending, data: list } = useFetch('/api/todo', {
lazy: true,
server: false
})
如果想要手動更新資料可以使用 refresh
。
<template>
<div>
...
<button @click="refresh">Refresh data</button>
</div>
</template>
<script setup lang="ts">
const { data:list, error, execute, refresh } = await useFetch('/api/todo')
</script>
如果想要監聽某個值並更新資料可以使用 watch
,可以監聽一個或多個元素。
const id = ref(1)
const { data:list, error, refresh } = await useFetch('/api/todo', {
watch: [id]
})
$fetch
& useAsyncData
$fetch
是 Nuxt 3 提供用來獲取資料的 Utils,讓我們不需要額外安裝套件即可進行 HTTP 請求。
在元件中直接使用 $fetch
會導致重複取得資料(SSR 時在伺服器端取得一次、Hydration 時再次取得),因為 $fetch
不會將狀態從伺服器傳遞到客戶端。
...
// 這邊會執行兩次
list.value = await $fetch('/api/todo')
...
為了避免在元件中重複取得資料的問題,官方文件明確建議使用 useFetch
或 useAsyncData + $fetch
,這樣可以確保資料在伺服器端取得後能傳遞到客戶端。
...
list.value = await useAsyncData('todo', () => $fetch('/api/todo'))
...
也可以在客戶端的事件裡直接使用 fetch
// app.vue
<template>
...
<button type="button" @click="Post">Submit</button>
</template>
<script setup lang="ts">
...
const Post = async () => {
await $fetch('/api/todo', {
method: 'post',
body: { name: todo.value }
})
}
...
</script>
以開發的角度來說使用 useFetch
較為方便,不管什麼情況 useFetch
都有相對應的設定,反而 $fetch
和 useAsyncData
在使用上有許多要注意的地方,一不小心可能就會踩到雷。
這幾天介紹了 Server API 的使用方式及取得資料的方法,明天會介紹用於轉場的效果 Transitions 。
Data fetching
useFetch
useAsyncData
fetch