useNuxtData
概述useNuxtData
是 Nuxt 3 中的一个组合函数,用于访问通过其他数据获取函数(如useAsyncData
、useLazyAsyncData
、useFetch
和useLazyFetch
等)缓存的数据。它允许在不同的组件之间共享数据,避免重复请求,提高性能。
1. 获取数据并缓存
在pages/posts.vue
中,我们可以使用useFetch
来获取帖子数据,并将其缓存到posts
键名下:
// pages/posts.vue
<script setup>
// 使用 useFetch 获取数据并缓存
const { data, error } = await useFetch('/api/posts', { key: 'posts' })
// 处理错误
if (error.value) {
console.error('获取帖子失败:', error.value)
}
</script>
<template>
<div>
<h1>帖子列表</h1>
<ul>
<li v-for="post in data" :key="post.id">{{ post.title }}</li>
</ul>
</div>
</template>
2. 访问缓存数据
在pages/posts/[id].vue
中,我们可以使用useNuxtData
来访问posts.vue
中缓存的帖子数据:
// pages/posts/[id].vue
<script setup>
import { useRoute } from 'vue-router'
// 获取路由参数
const { id } = useRoute().params
// 访问缓存的帖子数据
const { data: posts } = useNuxtData('posts')
// 使用 useLazyFetch 获取单个帖子的详细信息
const { data, error } = useLazyFetch(`/api/posts/${id}`, {
key: `post-${id}`,
default() {
// 从缓存中找到对应的帖子,并将其设置为默认值
return posts.value.find(post => post.id === id) || null
}
})
// 处理错误
if (error.value) {
console.error('获取帖子详情失败:', error.value)
}
</script>
<template>
<div>
<h1>帖子详情</h1>
<div v-if="data">
<h2>{{ data.title }}</h2>
<p>{{ data.content }}</p>
</div>
</div>
</template>
3. 更新
在pages/todos.vue
中,我们可以使用useAsyncData
来获取待办事项,并在添加新待办事项时利用缓存进行乐观更新:
// pages/todos.vue
<script setup>
// 获取待办事项数据并缓存
const { data: todos, error } = await useAsyncData('todos', () => $fetch('/api/todos'))
// 处理错误
if (error.value) {
console.error('获取待办事项失败:', error.value)
}
</script>
<template>
<div>
<h1>待办事项</h1>
<ul>
<li v-for="todo in todos" :key="todo.id">{{ todo.task }}</li>
</ul>
<NewTodo />
</div>
</template>
在components/NewTodo.vue
中,我们可以实现添加新待办事项的逻辑:
// components/NewTodo.vue
<script setup>
import { ref } from 'vue'
const newTodo = ref('')
const previousTodos = ref([])
// 访问 todos.vue 中 useAsyncData 的缓存值
const { data: todos } = useNuxtData('todos')
const addTodo = async () => {
const { data, error } = await useFetch('/api/addTodo', {
method: 'post',
body: {
todo: newTodo.value
},
onRequest() {
// 在请求开始时保存当前的 todos 数据
previousTodos.value = [...todos.value]
// 乐观更新 UI
todos.value.push({ id: Date.now(), task: newTodo.value }) // 假设 ID 为当前时间戳
},
onRequestError() {
// 请求失败时回滚数据
todos.value = previousTodos.value
},
async onResponse() {
// 请求成功后刷新 todos 数据
await refreshNuxtData('todos')
}
})
// 清空输入框
newTodo.value = ''
}
</script>
<template>
<div>
<input v-model="newTodo" placeholder="添加新待办事项" />
<button @click="addTodo">添加</button>
</div>
</template>
useNuxtData
的类型定义如下:
useNuxtData<DataT = any> (key: string): { data: Ref<DataT | null> }
key
: 用于访问缓存数据的键名。data
: 返回一个响应式引用,包含缓存的数据或null
。useNuxtData
时,提供的键名与之前缓存数据时使用的键名一致。