You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Nuxt 3如何实现带Payload的动态路由预渲染?

在Nuxt 3中替代Nuxt 2预渲染路由payload的实现方案

我在Nuxt 2里通过nuxt.config.js的generate async routes函数,借助Contentful的数据预渲染路由——先拉取所有相关Contentful数据,遍历生成路由的同时通过payload传递数据。但转到Nuxt 3后,找不到对应的实现方式:目前用prerender:routes钩子生成了路由,但这个钩子没有payload选项,导致页面拿不到正确的数据。

Nuxt 2 实现代码(nuxt.config.js)

generate: {
      fallback: true,
      crawler: false,
      async routes() {
        const courses = (
          await fetchEntriesByContentType({ contentType: "courses" })
        ).map((entry) => ({
          route: `/courses/${entry.fields.slug}`,
          payload: entry,
        }));
        const jobs = (
          await fetchEntriesByContentType({ contentType: "job" })
        ).map((entry) => ({
          route: `/jobs/${entry.fields.slug}`,
          payload: entry,
        }));
        return [...courses, ...jobs];
      }
}

Nuxt 3 当前实现(nuxt.config.js)

hooks: {
        'prerender:routes': async function (ctx) {
          try {
            Promise.all([
              client.getEntries({
                content_type: "courses"
              }),
              client.getEntries({
                content_type: "job"
              })
            ])
            .then(([courses, jobs]) => {
              for (const course of courses.items) {
                ctx.routes.add(`/courses/${course.fields.slug}/`);
              }
              for (const job of jobs.items) {
                ctx.routes.add(`/jobs/${job.fields.slug}/`);
              }
            })
          } catch (error) {
            console.error('Error fetching data:', error);
          }
        }
    }

Nuxt 3 替代方案

Nuxt 3不再支持直接通过路由钩子传递payload,但可以通过两种方式实现类似效果:

1. 页面组件内直接获取数据(推荐)

在对应页面组件(如pages/courses/[slug].vue)中,使用useAsyncData或useFetch在预渲染/服务端阶段拉取对应数据:

<script setup>
const route = useRoute();
const { data: course } = await useAsyncData(`course-${route.params.slug}`, async () => {
  const res = await client.getEntries({
    content_type: "courses",
    'fields.slug': route.params.slug
  });
  return res.items[0];
});
</script>

预渲染时Nuxt会自动执行该逻辑,将数据注入静态页面,无需额外传递payload。

2. 利用nitro:prerender钩子存储数据(进阶)

如果需要在预渲染阶段提前准备好所有数据,可使用nitro:prerender钩子将数据存入应用配置,再在页面中读取:

// nuxt.config.js
export default defineNuxtConfig({
  hooks: {
    async 'nitro:prerender'({ routes, nuxt }) {
      // 拉取所有Contentful数据
      const [coursesRes, jobsRes] = await Promise.all([
        client.getEntries({ content_type: "courses" }),
        client.getEntries({ content_type: "job" })
      ]);
      // 将数据存入应用配置
      nuxt.options.appConfig.prerenderData = {
        courses: coursesRes.items,
        jobs: jobsRes.items
      };
      // 添加预渲染路由
      coursesRes.items.forEach(course => routes.add(`/courses/${course.fields.slug}`));
      jobsRes.items.forEach(job => routes.add(`/jobs/${job.fields.slug}`));
    }
  }
});

页面中读取数据:

<script setup>
const route = useRoute();
const appConfig = useAppConfig();
const course = appConfig.prerenderData.courses.find(c => c.fields.slug === route.params.slug);
</script>

内容的提问来源于stack exchange,提问作者user2953989

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 16:57:21