如何基于WP-API在Nuxt中生成带父级的多层动态路由?
当然可以实现这种带父级的嵌套路由!
我之前在WP-API + Nuxt的项目里处理过完全一样的需求,给你两个最实用的方案,适配不同版本的Nuxt:
方案一:Nuxt 2 实现方式
1. 配置静态生成路由
在nuxt.config.js里,我们需要从WP-API拉取所有页面数据,根据页面的父级关系自动构建完整的路由路径:
export default { generate: { async routes() { // 拉取WP所有页面数据(注意调整per_page确保覆盖所有页面) const res = await fetch('https://你的WP站点域名/wp-json/wp/v2/pages?per_page=100') const pages = await res.json() // 递归构建带父级的完整路径 const buildFullPath = (page) => { let path = `/${page.slug}` let parentPage = pages.find(p => p.id === page.parent) // 循环向上查找所有父级页面,拼接路径 while (parentPage) { path = `/${parentPage.slug}${path}` parentPage = pages.find(p => p.id === parentPage.parent) } return path } // 返回所有页面的路由配置,同时传递页面数据作为payload避免重复请求 return pages.map(page => ({ route: buildFullPath(page), payload: page })) } } }
2. 创建Catch-All组件
在pages目录下新建_.vue(这是Nuxt 2的全局捕获路由组件),用来处理所有层级的页面请求:
<template> <div v-if="page"> <h1>{{ page.title.rendered }}</h1> <div v-html="page.content.rendered"></div> </div> </template> <script> export default { async asyncData({ params, error, payload }) { // 如果是静态生成阶段传递的payload,直接使用 if (payload) { return { page: payload } } // 动态请求阶段:从路由参数中解析完整slug路径 const fullSlug = params.pathMatch // params.pathMatch会拿到比如"company/about"这样的字符串 const res = await fetch(`https://你的WP站点域名/wp-json/wp/v2/pages?slug=${fullSlug}`) const pages = await res.json() if (pages.length === 0) { error({ statusCode: 404, message: '页面不存在' }) } return { page: pages[0] } } } </script>
方案二:Nuxt 3 实现方式
Nuxt 3的路由系统更灵活,用Catch-All路由结合Nitro预渲染即可:
1. 配置预渲染路由
在nuxt.config.ts中配置Nitro的预渲染规则,自动生成所有带父级的页面路由:
export default defineNuxtConfig({ nitro: { prerender: { async routes() { const res = await fetch('https://你的WP站点域名/wp-json/wp/v2/pages?per_page=100') const pages = await res.json() const buildFullPath = (page) => { let path = `/${page.slug}` let parentPage = pages.find(p => p.id === page.parent) while (parentPage) { path = `/${parentPage.slug}${path}` parentPage = pages.find(p => p.id === parentPage.parent) } return path } return pages.map(page => buildFullPath(page)) } } } })
2. 创建Catch-All组件
在pages目录下新建[...slug].vue:
<script setup> const route = useRoute() // 根据路由参数拼接完整slug路径 const fullSlug = route.params.slug?.join('/') || '' // 请求WP-API获取页面数据 const { data: page } = await useAsyncData(`page-${fullSlug}`, async () => { const res = await $fetch(`https://你的WP站点域名/wp-json/wp/v2/pages?slug=${fullSlug}`) return res[0] || null }) // 页面不存在时抛出404 if (!page.value) { throw createError({ statusCode: 404, message: '页面不存在' }) } </script> <template> <div v-if="page"> <h1>{{ page.title.rendered }}</h1> <div v-html="page.content.rendered"></div> </div> </template>
关键注意事项
- 确保你的WordPress固定链接设置为「帖子名称」模式,这样WP-API返回的页面slug层级关系是正确的
- 如果页面数量超过100,记得调整WP-API请求的
per_page参数(WP默认最大100,需要的话可以在WP后台修改API限制) - 静态生成时,要确保所有页面都被正确抓取到,避免出现404页面
内容的提问来源于stack exchange,提问作者Daniel Oshiro
相关产品推荐
相关产品推荐

