我在 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
。这是该问题的重现。
这是一个错误还是我在这里做错了什么?
我之前在访问布局中的路由参数时遇到了同样的问题。我不确定这是否与
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>
已测试,有效。
只是在这里添加一个“快捷方式”: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”被缓存