Nuxt 3中如何向嵌套页面传递选中文章数据以避免重复请求?
在Nuxt中传递选中的文章到嵌套页面(避免重复请求)
你不需要传递整个文章列表,下面两种方案可以直接传递选中的单篇文章,同时避免重复请求:
方法一:通过NuxtLink的路由state传递单篇文章
这是最轻量化的方案,无需额外依赖,跳转时直接把选中的文章放入路由state:
修改列表页面(pages/articles.vue)
<template> <NuxtLink v-for="article in articles" :key="article.id" :to="{ path: `/articles/${article.id}`, state: { selectedArticle: article } }" > {{ article.title }} </NuxtLink> <NuxtPage /> </template> <script setup> const { data: articles } = useFetch('/articles/') </script>
修改子页面(pages/articles/[articleId].vue)
从路由state中直接获取文章,同时添加降级逻辑(应对用户直接刷新子页面的情况):
<template> <h1>{{ article.title }}</h1> <main>{{ article.body }}</main> </template> <script setup> const route = useRoute() let article = route.state?.selectedArticle // 如果路由state中无数据(比如刷新页面),则重新请求 if (!article) { const { data: fetchedArticle } = useFetch(`/articles/${route.params.articleId}`) article = fetchedArticle.value } </script>
方法二:使用Pinia状态管理(适合复杂应用)
如果你的应用需要在多个组件中共享选中的文章状态,用Pinia存储会更灵活:
1. 创建Pinia Store
在stores/article.js中创建状态管理文件:
import { defineStore } from 'pinia' export const useArticleStore = defineStore('article', { state: () => ({ selectedArticle: null }), actions: { setSelectedArticle(article) { this.selectedArticle = article } } })
2. 修改列表页面(pages/articles.vue)
点击链接时将选中的文章存入Store:
<template> <NuxtLink v-for="article in articles" :key="article.id" :to="`/articles/${article.id}`" @click="store.setSelectedArticle(article)" > {{ article.title }} </NuxtLink> <NuxtPage /> </template> <script setup> import { useArticleStore } from '~/stores/article' const { data: articles } = useFetch('/articles/') const store = useArticleStore() </script>
3. 修改子页面(pages/articles/[articleId].vue)
从Store中获取文章,同时校验ID匹配度并添加降级逻辑:
<template> <h1>{{ article.title }}</h1> <main>{{ article.body }}</main> </template> <script setup> import { useArticleStore } from '~/stores/article' const route = useRoute() const store = useArticleStore() let article = store.selectedArticle // 校验文章ID是否匹配,或Store无数据时重新请求 if (!article || article.id !== route.params.articleId) { const { data: fetchedArticle } = useFetch(`/articles/${route.params.articleId}`) article = fetchedArticle.value store.setSelectedArticle(article) } </script>
关键注意点
- 两种方案都必须添加降级处理:因为用户直接刷新子页面时,路由state或Store中的临时数据会丢失,此时必须重新请求服务器数据,保证页面正常渲染。
- 方法一适合简单场景,无需额外依赖;方法二更适合多组件共享选中状态的复杂应用。
内容的提问来源于stack exchange,提问作者Pawel Decowski
相关产品推荐
相关产品推荐

