基于Nuxt 3新模块系统的渲染钩子及相关需求咨询
Nuxt 3 SSG 模块开发解决方案
1. 页面渲染前挂载钩子
在 SSG 模式下,可通过 Nuxt 内置钩子实现页面渲染前的逻辑执行,推荐两种场景化方案:
SSG 预渲染专属钩子
在 module.ts 中监听 nitro:prerender:route,该钩子会在预渲染每个路由时触发,适合处理静态生成阶段的前置逻辑:
export default defineNuxtModule({ setup(options, nuxt) { nuxt.hook('nitro:prerender:route', async (route) => { // 页面预渲染前执行的逻辑,比如拉取静态数据、修改路由元信息 console.log(`Pre-rendering route: ${route.route}`) // 可将自定义数据存入 route.payload,页面中通过 useRoute().payload 获取 route.payload.pagePreloadData = await fetchStaticData(route.route) }) } })
页面解析阶段钩子
若需在页面组件解析完成后、渲染前执行逻辑,使用 page:resolve 钩子:
nuxt.hook('page:resolve', async (page) => { // page 对象包含当前页面的路径、组件、元信息等 if (page.path.startsWith('/blog')) { // 针对特定页面组执行前置逻辑 page.meta.blogPreload = await getBlogCategoryData() } })
2. 实现类似 Next.js getStaticProps 的页面数据注入
通过「自定义页面导出函数 + 模块钩子」的组合,让页面可导出 getStaticProps 并在 SSG 阶段执行,将数据注入页面:
步骤1:模块中注册钩子处理逻辑
export default defineNuxtModule({ setup(options, nuxt) { nuxt.hook('nitro:prerender:route', async (route) => { // 解析当前路由对应的页面组件 const pageComponent = await nuxt.resolvePageComponent(route.route) if (pageComponent?.getStaticProps) { // 执行页面导出的 getStaticProps 函数 const staticProps = await pageComponent.getStaticProps({ route: route.route }) // 将数据存入路由 payload route.payload.staticProps = staticProps } }) } })
步骤2:页面中定义并使用数据
在页面组件中导出 getStaticProps:
<script setup> import { useRoute } from 'vue-router' const route = useRoute() // 获取模块注入的静态数据 const { title, content } = route.payload.staticProps || {} </script> <script> // 导出供模块调用的 getStaticProps export async function getStaticProps(context) { return { title: 'SSG 页面标题', content: await fetchArticleContent(context.route) } } </script>
也可封装成 Composable 简化调用:
// 模块中注册 Composable nuxt.hook('app:setup', (app) => { app.provide('useStaticProps', () => { const route = useRoute() return route.payload.staticProps || {} }) })
页面中直接使用:
<script setup> const staticProps = inject('useStaticProps')() </script>
3. 在 module.ts 和插件间共享全局对象
两种可靠的共享方式:
方式1:挂载到 Nuxt 实例
在 module.ts 中将全局对象挂载到 nuxt 实例,插件通过 nuxtApp._nuxt 访问:
// module.ts export default defineNuxtModule({ setup(options, nuxt) { // 定义全局对象 nuxt.$myModuleGlobal = { moduleConfig: options, sharedState: {}, utils: { formatDate: (date) => new Date(date).toLocaleDateString() } } } })
// 插件文件 plugins/my-plugin.ts export default defineNuxtPlugin(nuxtApp => { // 访问模块全局对象 const globalObj = nuxtApp._nuxt.$myModuleGlobal // 使用全局方法 const formattedDate = globalObj.utils.formatDate(new Date()) })
方式2:依赖注入(支持组件访问)
若需组件也能访问全局对象,通过 app.provide 实现:
// module.ts export default defineNuxtModule({ setup(options, nuxt) { const globalObj = { moduleConfig: options, sharedState: {} } // 注册依赖注入,供组件和插件使用 nuxt.hook('app:setup', (app) => { app.provide('myModuleGlobal', globalObj) }) // 同时挂载到 Nuxt 实例,供插件直接访问 nuxt.$myModuleGlobal = globalObj } })
插件和组件中通过 inject 获取:
// 插件中 const globalObj = inject('myModuleGlobal') // 组件中 <script setup> const globalObj = inject('myModuleGlobal') </script>
内容的提问来源于stack exchange,提问作者J. Langer
相关产品推荐
相关产品推荐

