useRoute().params初始加载为空,刷新后正常的问题求助
问题分析与解决方案
问题根源
客户端路由跳转(比如从组件1点击跳转)时,onBeforeMount钩子执行时机早于路由参数的更新完成,此时useRoute().params.id还未被正确注入,导致获取空值;而手动刷新页面属于服务端渲染/硬加载,路由参数在组件挂载前就已解析完成,所以能正常获取。另外当前代码仅在组件挂载前执行一次getTweet,后续路由参数变化时不会重新触发数据获取。
修复方案
方案1:使用Nuxt推荐的useAsyncData获取数据
Nuxt3的useAsyncData会自动适配服务端/客户端渲染场景,同时监听路由变化,确保路由参数可用:
<template> <div> <MainSection title="Tweet" :loading="pending"> <Head> <Title>{{ tweet?.content || 'Tweet' }}</Title> </Head> <TweetDetails :user="user" :tweet="tweet" /> </MainSection> </div> </template> <script setup> const route = useRoute(); const { useAuthUser } = useAuth(); const user = useAuthUser(); const { data: tweet, pending } = useAsyncData('tweet', async () => { const { getTweetById } = useTweets(); const response = await getTweetById(route.params.id); return response.tweet; }, { watch: [route.params.id] // 监听路由id变化,自动重新获取数据 }); </script>
方案2:调整钩子时机+监听路由参数
如果不想使用useAsyncData,可以修改钩子并监听路由变化:
<template> <div> <MainSection title="Tweet" :loading="loading"> <Head> <Title> </Title> </Head> <TweetDetails :user="user" :tweet="tweet" /> </MainSection> </div> </template> <script setup> const loading = ref(false); const { getTweetById } = useTweets(); const tweet = ref(null); const route = useRoute(); const { useAuthUser } = useAuth(); const user = useAuthUser(); async function getTweet() { if (!route.params.id) return; // 避免空id发起无效请求 loading.value = true; try { const response = await getTweetById(route.params.id); tweet.value = response.tweet; } catch (error) { console.log(error); } finally { loading.value = false; } } // 组件挂载后执行首次数据获取 onMounted(() => { getTweet(); }); // 监听路由id变化,重新获取对应数据 watch(() => route.params.id, () => { getTweet(); }); </script>
额外优化:组件1路由跳转优化
组件1中可以直接用NuxtLink替代手动router.push,更符合Nuxt路由最佳实践,还支持预加载特性:
<!-- 替换组件1中点击触发跳转的span --> <NuxtLink :to="replyToTweetUrl" class="text-blue-400"> {{ props.tweet.replyTo.author.handle }} </NuxtLink>
此写法可删除原有的doSomething函数,简化代码逻辑。
内容的提问来源于stack exchange,提问作者Kenza
相关产品推荐
相关产品推荐

