在 Nuxt4 中应使用 @pinia/nuxt 模块自动集成 Pinia,无需手动创建实例;Store 必须置于 stores/ 目录,支持 Setup/Option 两种写法;通过自动导入直接调用 useXxxStore();持久化需配合 pinia-plugin-persistedstate 并启用 SSR 安全策略。

在 Nuxt(尤其是 Nuxt4)中正确配置和使用 Pinia,关键在于利用其官方模块 `@pinia/nuxt`,它已深度适配 SSR/SSG 场景,自动处理服务端状态序列化、客户端水合(hydration)、HMR 和类型推导。不需要手动创建 Pinia 实例或在 `main.ts` 中调用 `app.use()` —— 这是 Nuxt3/Nuxt4 与纯 Vue 项目最核心的区别。
安装与模块注册
使用包管理器安装官方 Nuxt 模块:
- pnpm add @pinia/nuxt(推荐,Nuxt 官方默认工具链)
- 或 yarn add @pinia/nuxt / npm install @pinia/nuxt
然后在 nuxt.config.ts 中启用模块:
export default defineNuxtConfig({
modules: ['@pinia/nuxt'],
pinia: {
autoImports: ['defineStore']
}
})Store 文件位置与结构规范
Nuxt 要求 Store 必须放在 stores/ 目录下(项目根目录),且文件名即为 store ID(如 stores/user.ts → ID 为 'user')。支持两种写法,推荐 Setup 语法(更易读、类型更稳):
-
Option Store(传统写法):
// stores/counter.ts<br>import { defineStore } from 'pinia'<br>export const useCounterStore = defineStore('counter', {<br> state: () => ({ count: 0 }),<br> getters: { double: (state) => state.count * 2 },<br> actions: { increment() { this.count++ } }<br>}) -
Setup Store(推荐):
// stores/cart.ts<br>import { defineStore } from 'pinia'<br>import { ref, computed } from 'vue'<br>export const useCartStore = defineStore('cart', () => {<br> const items = ref([])<br> const total = computed(() => items.value.reduce((s, i) => s + i.price, 0))<br> function addItem(item) { items.value.push(item) }<br> return { items, total, addItem }<br>})
在页面/组件中直接使用(零导入)
得益于 Nuxt 的自动导入机制(autoImports: ['defineStore'] + stores/ 目录约定),你无需 import 任何 store 文件:
- 在
.vue或.ts文件中直接调用useCounterStore() - 服务端渲染时,store 状态会在服务端初始化并随 HTML 一起下发;客户端挂载时自动水合,保持状态一致
- 示例(
pages/index.vue):<script setup><br>const counter = useCounterStore()<br></script><br><template><br> <div>{{ counter.count }} <button @click="counter.increment">+</button></div><br></template>
持久化与 SSR 兼容要点
若需 localStorage 持久化(如用户登录态),必须使用 pinia-plugin-persistedstate 并注意 SSR 安全性:
- 安装插件:
pnpm add pinia-plugin-persistedstate - 在
nuxt.config.ts中配置(Nuxt4 自动注入):pinia: {<br> plugins: ['pinia-plugin-persistedstate']<br>} - 在具体 store 中启用(仅对需要持久化的 store):
export const useUserStore = defineStore('user', {<br> // ...<br> persist: {<br> enabled: true,<br> paths: ['token', 'profile'] // 可选:只持久化部分字段<br> }<br>}) - 注意:插件默认跳过服务端执行,避免 SSR 报错;浏览器环境才写入 localStorage


















