nuxt3:如何在页面中间件中访问获取的数据

问题描述 投票:0回答:2

我正在开发一个 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.js vuejs3 nuxtjs3
2个回答
1
投票

您需要存储数据,我是 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 框架)还很陌生,如果我在这里遗漏了一些东西,任何更好的解决方案都会受到欢迎。


0
投票

随着@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
数据。

© www.soinside.com 2019 - 2024. All rights reserved.