news 2026/9/6 22:02:03

airi 中的 Pinia 与 Nuxt 3/4 集成:自动导入、SSR 数据获取与插件扩展实践

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
airi 中的 Pinia 与 Nuxt 3/4 集成:自动导入、SSR 数据获取与插件扩展实践

airi 中的 Pinia 与 Nuxt 3/4 集成:自动导入、SSR 数据获取与插件扩展实践

【免费下载链接】airi💖🧸 Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-sama's altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi

本文基于 airi 仓库内置的 Pinia 技能参考文档 advanced-nuxt.md,完整讲解@pinia/nuxt的安装配置、自动导入机制、callOnceSSR 数据获取、组件外使用 store 以及 Nuxt 插件式扩展 Pinia 的五类核心场景,并结合 airi 单仓中真实的 Pinia 装配源码,帮助你在 Nuxt 与纯 Vite SPA 两种工程形态下都掌握 Pinia 的正确接线方式。

文档背景:它在 airi 技能体系中的位置

这篇集成文档位于 .agents/skills/pinia/references/advanced-nuxt.md,是 Pinia 技能入口 下 “Advanced” 主题之一,与 SSR 状态水合、HMR 支持 和 插件机制 等参考文档并列。技能入口中注明其基于 Pinia v3.0.4、生成于 2026-01-28;而 airi 工作区在 pnpm-workspace.yaml 中通过 catalog 统一锁定了pinia: ^4.0.3,并同时引入了@pinia/colada(数据获取)与@pinia/testing(测试)。因此本文内容适用于 Nuxt 3/4 + Pinia 3/4 时代的项目;阅读下文配置示例时,请以当前仓库实际依赖版本为准。

安装:一条 nuxi 命令与 npm ERESOLVE 陷阱

Pinia 与 Nuxt 3/4 的集成由官方 Nuxt 模块@pinia/nuxt承担,SSR、状态序列化与 XSS 防护均被模块自动处理。标准安装方式为:

npx nuxi@latest module add pinia

该命令会同时安装@pinia/nuxtpinia两个包;如果本地已有旧版pinia残留,需要手动补齐缺失的一方。

文档特别提示了一个 npm 用户常见坑:若安装时报ERESOLVE unable to resolve dependency tree,应在package.json中声明依赖覆盖:

"overrides": { "vue": "latest" }

这一点在 airi 仓库有对应的工程语境:airi 使用 pnpm workspace 而非 npm overrides,版本一致性改由 catalog 保证——pnpm-workspace.yaml 中pinia: ^4.0.3@pinia/colada: ^1.4.2@pinia/testing: ^2.0.1等条目被各 app 与 package 以"pinia": "catalog:"形式引用(如 apps/stage-web/package.json、packages/stage-ui/package.json)。两种做法目的相同:避免多个 Vue/Pinia 副本并存导致的响应式断裂。

nuxt.config.ts 配置与自动导入

最小配置

nuxt.config.ts中注册模块即可:

// nuxt.config.ts export default defineNuxtConfig({ modules: ['@pinia/nuxt'], })

模块自动提供的 API

启用模块后,以下 API 无需手动 import,在<script setup>中直接可用:

  • usePinia()— 获取当前 pinia 实例;
  • defineStore()— 定义 store;
  • storeToRefs()— 从 store 解构并保持响应性的 refs;
  • acceptHMRUpdate()— 开发期热更新支持。

更关键的是store 的自动导入app/stores/(Nuxt 4 目录约定)或stores/下的所有 store 会被模块自动导入,页面中可直接useXxxStore()而无需导入语句。这与 airi 的 Vite SPA 形成鲜明对照——apps/stage-web/src/stores 下的background.tsdevtools-lag.tspwa.ts都需要在组件中显式导入使用,Nuxt 模块省掉的正是这类样板代码。

自定义 Store 目录

当 store 分散在多个目录时,可用storesDirs配置多个 glob:

// nuxt.config.ts export default defineNuxtConfig({ modules: ['@pinia/nuxt'], pinia: { storesDirs: ['./stores/**', './custom-folder/stores/**'], }, })

该配置让模块把额外的目录纳入自动导入扫描范围,适合将领域 store 按业务模块组织的单仓项目。

SSR 友好的数据获取:callOnce

页面中获取数据时,推荐使用模块提供的callOnce(),它在 SSR 与水合阶段天然安全:

<script setup> const store = useStore() // 只运行一次,数据在后续导航间持久保留 await callOnce('user', () => store.fetchUser()) </script>

第一个参数是缓存键,callOnce以该键保证同一请求在整个应用会话中只执行一次,导航到其它页面再回来时直接使用已缓存的结果。若业务上希望“每次导航都重新拉取”(行为对齐 Nuxt 的useFetch),则传入navigation模式:

<script setup> const store = useStore() // 每次导航都重新获取(类似 useFetch) await callOnce('user', () => store.fetchUser(), { mode: 'navigation' }) </script>

两者覆盖了“会话级一次性数据”与“导航级新鲜数据”两类最常见的服务端取数语义。

在组件之外使用 Store:显式传递 pinia 实例

在导航守卫、中间件或普通工具函数中,没有 Vue 注入上下文,store 无法自动解析 pinia 实例。此时需从useNuxtApp()取出$pinia显式传入。文档给出的路由中间件示例:

// middleware/auth.ts export default defineNuxtRouteMiddleware((to) => { const nuxtApp = useNuxtApp() const store = useStore(nuxtApp.$pinia) if (to.meta.requiresAuth && !store.isLoggedIn) { return navigateTo('/login') } })

文档同时强调:大多数场景不需要这样做——在组件或任何有注入能力的上下文中,直接调用useStore()即可。

在 Nuxt 中使用 Pinia 插件

@pinia/nuxt把 pinia 实例挂载为nuxtApp.$pinia,因此注册 Pinia 插件的自然位置是一个 Nuxt 插件。文档示例:

// plugins/myPiniaPlugin.ts import { PiniaPluginContext } from 'pinia' function MyPiniaPlugin({ store }: PiniaPluginContext) { store.$subscribe((mutation) => { console.log(`[🍍 ${mutation.storeId}]: ${mutation.type}`) }) return { creationTime: new Date() } } export default defineNuxtPlugin(({ $pinia }) => { $pinia.use(MyPiniaPlugin) })

要点有两处:一是利用store.$subscribe监听 mutation 做日志/埋点,二是插件函数可以返回额外属性(如creationTime)合并进 store。

airi 单仓中的对应实践:手动装配等价链路

airi 的各端应用是 Vite + Vue SPA(而非 Nuxt),但走的是同一套pinia.use()插件机制。以 apps/stage-web/src/main.ts 为例:

const pinia = createPinia() const synced = setupSynced() pinia.use(synced.pinia) if (import.meta.env.DEV) pinia.use(piniaPluginTracing)

随后在createApp(App).use(pinia).use(PiniaColada)中先装 pinia 再装@pinia/colada插件——插件注册顺序(必须在 pinia 插件之后)与 Nuxt 插件写法中的$pinia.use是同一约束。这里的synced.pinia来自 packages/stage-ui/src/libs/pinia/setup-synced.ts,它封装了pinia-plugin-synced库,配置了命名空间airi:stage:pinia与 5 分钟的callTimeout,用于在 Stage 的多渲染窗口之间做状态快照复制与领导者路由调用;仓库 AGENTS.md 也明确将其定位为“快照复制 + 领导者路由 RPC,不跨渲染器共享 Vue refs”。从源码结构看,这段手动装配等价于@pinia/nuxt在 Nuxt 项目中自动完成的工作:创建实例、按序挂插件、注入到应用。此外开发环境特有的pinia.use(piniaPluginTracing)也示范了插件“按环境条件挂载”的常见写法。

要点回顾

  • 安装用npx nuxi@latest module add pinia;npm 遇到ERESOLVE时用overrides固定vue版本。
  • @pinia/nuxt提供usePinia/defineStore/storeToRefs/acceptHMRUpdate的自动导入,并自动导入app/stores/(Nuxt 4)或stores/下的全部 store;多目录场景用pinia.storesDirs扩展。
  • 页面取数用callOnce控制“一次执行”与“按导航刷新”两种语义。
  • 组件外(中间件、守卫)使用 store 时通过useNuxtApp().$pinia显式传入实例。
  • Pinia 插件通过 Nuxt 插件中的$pinia.use()注册;airi 在纯 SPA 工程中的createPinia+pinia.use(...)装配是同一机制的手动版本,两者可互相参照理解。

【免费下载链接】airi💖🧸 Self hosted, you-owned Grok Companion, a container of souls of waifu, cyber livings to bring them into our worlds, wishing to achieve Neuro-sama's altitude. Capable of realtime voice chat, Minecraft, Factorio playing. Web / macOS / Windows supported.项目地址: https://gitcode.com/GitHub_Trending/ai/airi

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/6 21:59:58

储能与可调负荷联合调度:可调节能力评估与MILP实现

简介&#xff1a;面向电力系统、智能电网与新能源领域的研究人员与工程师&#xff0c;这份文档以Python完整复现了双碳目标下需求侧资源可调节能力评估与优化调度研究。内容覆盖需求侧资源通用建模&#xff0c;包括功率容量、爬坡速率与状态约束&#xff0c;并实现多时段可调节…

作者头像 李华
网站建设 2026/9/6 21:58:24

化工厂巡检路径规划建模全解析:从Floyd到多人协作优化

简介&#xff1a;这份资源收录了2017年全国大学生数学建模竞赛高教杯奖D题的完整论文&#xff0c;主题为化工厂巡检路径规划与建模&#xff0c;适合数学建模参赛者、毕业设计学生及相关方向研究者参考。论文系统解决了巡检线路设计与排班优化问题&#xff0c;构建了以最少巡检人…

作者头像 李华
网站建设 2026/9/6 21:52:45

Android电视端BUG复现全攻略:从日志到自动化脚本

简介&#xff1a;面向Android智能电视应用开发者的技术资料&#xff0c;针对复杂BUG难以复现的痛点&#xff0c;提出基于软件实现的按键记录与自动回放方案。资源为单份PDF文档&#xff0c;体积约903KB&#xff0c;内容完整收录深圳创维-RGB电子有限公司工程师张帆的交流文章&a…

作者头像 李华