vue.js Nuxt 3中的布局/组件中未定义路由参数

fumotvh3  于 2023-05-01  发布在  Vue.js
关注(0)|答案(1)|浏览(220)

我在Nuxt 3的组件/布局中遇到了路由参数未定义的问题。它看起来像一个bug,但它将是一个如此关键的bug,我几乎不相信它可以是一个bug。
考虑以下文件:

// pages/index.vue
<template>
    <div>
        <NuxtLink to="/test-123">Click me</NuxtLink>
    </div>
</template>
// pages/test-[id].vue
<script setup lang="ts">
definePageMeta({ layout: "test" });
const route = useRoute();
console.log("page", route.params.id);
</script>

<template>
    <div>
        {{ route.params.id }}
    </div>
</template>
// layouts/test.vue
<script setup lang="ts">
const route = useRoute();
console.log("layout", route.params.id);
</script>

<template>
    <div>
        <test></test>
        <slot></slot>
    </div>
</template>
// components/test.vue
<script setup lang="ts">
const route = useRoute();
console.log("component", route.params.id);
</script>

<template>
    <div>
        {{ route.params.id }}
    </div>
</template>

单击该链接将给予以下控制台输出:

layout undefined       [test.vue:4:8](http://localhost:3001/_nuxt/layouts/test.vue)
component undefined    [test.vue:4:8](http://localhost:3001/_nuxt/components/test.vue)
page 123               [test-[id].vue:6:8](http://localhost:3001/_nuxt/pages/test-[id].vue)

如果我们使用NuxtLink从/导航到/test-123,并在布局、组件和页面中打印route.params.id,则只有页面能够访问ID。布局和组件将打印为undefined。如果我重新加载页面,组件,布局和页面都可以访问路由参数。因此,只有在从一个页面导航到另一个页面时才会出现问题。
我在Nuxt 3.4.2上这是一个reproduction的问题。
这是个bug还是我做错了什么?

5kgi1eie

5kgi1eie1#

我之前在布局中访问路由参数时遇到了同样的问题。我不确定这是否与NuxtLink组件有关。
这是我对它为什么这样做的理解。这是因为我认为NuxtLayout首先运行在NuxtPage之前🤔。NuxtLayout内部的组件也是一样的。但是,如果您尝试将test组件放置在页面中,它将显示参数id。
要解决这个问题,请使用middleware。正如Nuxt文档中所述,中间件非常适合在导航到特定路由之前提取您想要运行的代码。
~middlware/check-auth.ts

export default defineNuxtRouteMiddleware((to) => {
    console.log('Middleware', to.params.id)
})

这样,当您尝试导航到test-[id]页面时,它将显示参数id。
如果您想使用middleware中显示的参数id,可以使用useState组合,如下所示。
~middlware/check-auth.ts

export default defineNuxtRouteMiddleware((to) => {
    console.log('Middleware', to.params.id)
    useState('routeParamId', () => to.params.id)
})

您可以在layout中使用它。
~layouts/test.vue

<script setup lang="ts">
const paramId = useState('routeParamId')
console.log('ParamId is', paramId.value)
</script>

<template>
    <div>
        <slot></slot>
    </div>
</template>

在您的test-[id]页面中。~pages/test-[id].vue

<script setup lang="ts">
definePageMeta({ layout: "test", middleware: 'check-route' });
const route = useRoute();
</script>

<template>
    <div>
        {{ route.params.id }}
    </div>
</template>

测试和它的工作。

相关问题