我正在开发一个 Nuxt 3 项目,我对其中一个文件中的语法有疑问。
(我想让它对 SEO 更友好,所以我没有使用
pages/posts/[id].vue
,而是使用 pages/posts/[id]/[title].vue
。)
这是
setup
的pages/posts/[id]/[title].vue
部分的代码:
type Post {
title: string;
};
const route = useRoute();
const { data } = await useFetch(
`/posts/${route.params.id}`
) as {
data: Ref<Post>
};
definePageMeta({
middleware: [
(to: RouteLocationNormalized, from: RouteLocationNormalized) => {
// I want to access the fetched data here
if (to.params.title !== data.value.title) {
navigateTo(`/posts/${data.value.id}/${data.value.title}`);
}
}
]
});
但是,当我运行代码时,我收到一个
500
错误,并显示消息“数据未定义。”我知道我可以独立地在中间件中获取发布数据,但这会导致重复的请求,这不太理想。
如何改进我的代码以使其正常工作并仅发送一次请求?
非常感谢任何人的帮助!
您需要存储数据,我是 Nuxt 的新手,今天也有同样的问题,几分钟前就弄清楚了。
在您的中间件中:
const $store = useNuxtApp()
$store.$requestData = data.value
然后,在您的页面中:
<script setup>
const $store = useNuxtApp()
console.log('data', $store.$requestData)
const data = $store.$requestData;
</script>
当然,我对 Nuxt(或一般的 JS 框架)还很陌生,如果我在这里遗漏了一些东西,任何更好的解决方案都会受到欢迎。
随着@joelod的回答以及以下内容:
解决方案如下:
import { useNuxtApp, callWithNuxt } from '#app';
// fetch the post data only once in middleware instead of the outside
definePageMeta({
middleware: [
async (to: RouteLocationNormalized, from: RouteLocationNormalized) => {
const nuxtApp = useNuxtApp();
const { data: post } = await useFetch(
`/posts/${to.params.id}`
) as {
data: Ref<Post>
};
await callWithNuxt(
nuxtApp,
() => {
nuxtApp.$requestData = post.value;
}
);
}
]
});
const nuxtApp = useNuxtApp();
const route = useRoute();
const post: Ref<Post> = ref(nuxtApp.$requestData as Post);
if (to.params.title !== post.value.title) {
navigateTo(`/posts/${post.value.id}/${post.value.title}`);
}
// then you can use the `post` data anywhere
useSeoMeta({
title: `${post.value.title} | My Blog`,
});
PS:
在中间件之外编写
navigateTo()
可能是更好的做法,因为当 useFetch
收到错误时,例如 404 Not Found
或 429 Too Many Requests
,如果 [nuxt] A composable that requires access to the Nuxt instance was called outside of a plugin, Nuxt hook, Nuxt middleware, or Vue setup function
在中间件内部,页面可能会得到 navigateTo()
,因为您的 template
可能会使用 post
数据。