NuxtJS博客刷新详情页参数失效,触发读取author属性报错
问题原因分析与解决方案
首先咱们来拆解一下你遇到的问题:
核心原因:路由参数不匹配 + 刷新时隐式参数丢失
你通过nuxt-link跳转时传递了id参数,但你的路由category-slug的路径结构是/:category/:slug(从刷新后的URLtech/hello-world能看出来)——这个路由路径里并没有id这个动态段。
- 首次通过
nuxt-link跳转属于客户端导航,Nuxt会把你传入的所有参数(包括id)暂时存在内存里,所以context.params.id能拿到值,请求正常。 - 但刷新页面时,浏览器只会把URL中实际存在的参数(也就是
category和slug)传给应用,id这个没出现在URL里的参数直接丢失了,导致context.params.id变成undefined。这时候你的axios请求就变成了:
后端返回axios.get('https://howto-a9089.firebaseio.com/posts/undefined.json')null,你再访问loadedPost.author自然就抛出Cannot read property 'author' of null的错误。
针对性解决方案
方案1:把id加入路由路径(URL显式携带)
修改路由配置,让id成为URL的一部分,比如把路由路径改成/:category/:slug/:id。这样刷新页面时,id会作为URL的一部分被保留,context.params.id就能稳定获取到值。
对应的nuxt-link可以保持不变,刷新后的URL会变成类似tech/hello-world/123。
方案2:通过category+slug获取文章数据
如果不想修改URL结构,可以调整后端接口,支持通过category和slug查询文章。这样在asyncData里就可以用这两个参数请求数据:
asyncData(context) { const { category, slug } = context.params return axios.get(`https://howto-a9089.firebaseio.com/posts/${category}/${slug}.json`) .then(res => { return { loadedPost: res.data } }) }
不管是首次跳转还是刷新,都能拿到有效的参数,请求到正确的文章数据。
方案3:用查询参数(query)传递id
如果必须依赖id,可以把id作为查询参数传递,而不是路由params:
<nuxt-link :to="{ name: 'category-slug', params: { slug: slug, category: category }, query: { id: id } }">
然后在asyncData里通过context.query.id获取:
asyncData(context) { const postId = context.query.id if (!postId) { // 处理id不存在的情况,比如重定向到404 context.redirect('/404') return { loadedPost: {} } } return axios.get(`https://howto-a9089.firebaseio.com/posts/${postId}.json`) .then(res => { return { loadedPost: res.data } }) }
刷新后URL会变成tech/hello-world?id=123,查询参数会被保留,id就能正常获取。
额外建议:添加错误处理
不管用哪种方案,都建议在asyncData里添加错误处理,避免请求失败导致页面崩溃:
asyncData(context) { const postId = context.query.id // 或者对应的参数 if (!postId) { context.redirect('/404') return { loadedPost: {} } } return axios.get(`https://howto-a9089.firebaseio.com/posts/${postId}.json`) .then(res => { if (!res.data) { // 文章不存在的情况 context.redirect('/404') return { loadedPost: {} } } return { loadedPost: res.data } }) .catch(err => { console.error('请求文章失败:', err) context.redirect('/404') return { loadedPost: {} } }) }
内容的提问来源于stack exchange,提问作者Flæx
相关产品推荐
相关产品推荐

