必须使用@dcloudio/pinia而非官方pinia,因其专为uni-app多端定制,修复ssr时机、storage适配等问题;持久化须用pinia-plugin-unistorage,它自动路由至uni.setstoragesync/getstoragesync,避免小程序报错。

不能直接装官方 pinia,必须用 @dcloudio/pinia,否则小程序编译失败、H5 白屏或报 app.use is not a function。
安装和版本匹配必须严格对齐
uni-app 的 Vue 运行时是定制版,官方 pinia 依赖的标准 createApp 行为在小程序/APP 端不可用。DCloud 官方维护的 @dcloudio/pinia 才是唯一兼容方案。
- CLI 项目(非 HBuilderX 内置):运行
npm install @dcloudio/pinia—— 别装pinia,也别加版本号 - HBuilderX ≥ 4.14:虽已内置,但 CLI 项目仍需显式安装,否则构建时找不到模块
- 确认
uni-appCLI 版本 ≥ 3.9.0:npx uni-app -V或检查package.json中@dcloudio/uni-app版本 - 确保项目启用 Vue 3 模式:
"vueVersion": "3"需在vue.config.js或manifest.json中明确配置
main.js 中挂载方式和时机不能错
uni-app 不走标准 app.use(pinia) 流程,而是通过 uni.$pinia 全局注入。顺序错、位置错、包裹错,都会导致 store 返回 undefined。
- 入口文件必须导出
createApp函数,不能直接createSSRApp(App).mount() -
createPinia()必须在createSSRApp(App)之后、return之前调用 - 绝对不要用条件编译包裹 import 或初始化逻辑,例如
/* #ifdef MP-WEIXIN */ import { createPinia } ... /* #endif */—— JS 模块导入不参与条件编译,H5 端会报错 - 正确写法示例:
import { createSSRApp } from 'vue'
import App from './App.vue'
import { createPinia } from '@dcloudio/pinia'
<p>export function createApp() {
const app = createSSRApp(App)
const pinia = createPinia()
uni.$pinia = pinia // 关键:挂到 uni 实例
return { app, pinia }
}</p>
store 定义要避开小程序 Proxy 限制
小程序端的 Proxy 实现不完整,直接用 Map、Set、类实例或深层嵌套 reactive 对象,会导致响应式失效 —— 数据变了,视图不更新。
-
state必须是函数,且内部用ref或裸对象字面量返回,避免reactive({})包裹外部对象 - 错误写法:
state: () => reactive({ count: ref(0) })——ref被包在reactive里,失去响应性 - 推荐写法:
state: () => ({ count: 0 })或state: () => ({ count: ref(0) })(需配合storeToRefs解构使用) - 异步 action 中发请求,统一用
uni.request,禁用fetch或axios(小程序无window.fetch)
持久化必须用 pinia-plugin-unistorage
pinia-plugin-persistedstate 默认用 localStorage,在小程序和 App 端直接报错;pinia-plugin-unistorage 是专为 uni-app 设计的适配器,自动路由到 uni.setStorageSync 等跨端 API。
- 安装:
npm install pinia-plugin-unistorage - 注册插件必须在
app.use(pinia)之前,且显式传入 storage 适配器 - 只对需要持久化的 store 开启
persist,比如用户登录态、主题设置;loading、弹窗开关这类临时状态不该存 - 定义 store 时开启持久化示例:
import { defineStore } from 'pinia'
<p>export const useUserStore = defineStore('user', {
state: () => ({
token: '',
userInfo: null
}),
persist: true // 或 { key: 'user-store', paths: ['token'] }
})</p>
最易被忽略的是:store 文件里的 state 函数体内部,不能出现任何小程序不支持的 JS 类型(比如 new Date() 直接赋值),否则序列化进 storage 后再读取会变成空对象或 null —— 这类问题在 H5 上正常,一上真机就崩。










