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

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

我在 Nuxt 3 的组件/布局中遇到了路由参数未定义的问题。这看起来像是一个错误,但它将是一个非常严重的错误,我几乎不相信它会是一个错误。

考虑以下文件:

// 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。布局和组件将打印未定义。如果我重新加载页面,组件、布局和页面都可以访问路由参数。因此,仅当从一个页面导航到另一页面时才会出现此问题。

我在 Nuxt

3.4.2
。这是该问题的重现

这是一个错误还是我在这里做错了什么?

vue.js nuxt.js vue-router nuxtjs3
2个回答
2
投票

我之前在访问布局中的路由参数时遇到了同样的问题。我不确定这是否与

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>

已测试,有效。


0
投票

只是在这里添加一个“快捷方式”:ivan119 找到了一个对我有用的不同解决方案,如他对创建的 Github 问题 OP 的评论中所示:https://github.com/nuxt/nuxt/issues/20471 #issuecomment-1785954699

我花了很多时间才找到解决方案,请尝试

const route = useRouter().currentRoute.value
const id = route.params.id

由于某种原因“useRoute().params.id”被缓存

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