小程序端直接挂载 Vue.prototype 失效,因 uni-app 自研 runtime 不兼容标准 Vue 原型链注入;getApp().globalData 需配合 uni.setStorageSync 双向同步;Vuex 持久化须替换为 uni 接口;Pinia persist 插件需重写 getItem/setItem 为 uni 方法,并处理 null 返回值与读写时机错位问题。

为什么直接挂 Vue.prototype 在小程序端会失效
因为小程序平台的 Vue 实例是 uni-app 自研 runtime 封装的,并不完全兼容标准 Vue 的原型链注入机制。你在 main.js 里写 Vue.prototype.$token = 'xxx',H5 端可能跑得通,但微信/支付宝小程序里 this.$token 会是 undefined,且不会报错——只是静默丢失。更麻烦的是,这种写法绕过响应式系统,后续修改无法触发视图更新,调试时也看不到状态变化轨迹。
getApp().globalData 怎么配合 uni.setStorageSync 做自动同步
它本身不持久、不响应,但可以作为“内存缓存层” + “持久化桥接点”。关键在初始化和变更时双向对齐:
- App.vue 的
onLaunch中先从本地读:const saved = uni.getStorageSync('globalState');,再赋给getApp().globalData = { ...defaultState, ...saved } - 所有修改全局数据的地方(比如登录成功),必须同时写两处:
getApp().globalData.token = newToken和uni.setStorageSync('globalState', { token: newToken }) - 避免手动拼 key,建议封装一个函数统一管理:
function setGlobal(key, value) { getApp().globalData[key] = value; uni.setStorageSync('globalState', getApp().globalData); } - 注意:不要把函数、Date、RegExp 存进
globalData,否则uni.setStorageSync会序列化失败或静默丢弃
Vuex + 持久化插件在小程序端怎么配才不白屏
默认 vuex-persistedstate 用 localStorage,小程序根本不存在这个 API,直接报错或白屏。必须替换底层存储为 uni 兼容接口:
- 删掉
npm install vuex-persistedstate—— uni-app 内置 Vuex,额外装包反而冲突 - 改用轻量替代方案,在
store/index.js里手动加持久化逻辑:export default new Vuex.Store({<br> state: { token: '' },<br> mutations: {<br> SET_TOKEN(state, token) {<br> state.token = token;<br> uni.setStorageSync('token', token); // 同步落盘<br> }<br> },<br> actions: {<br> login({ commit }, token) {<br> commit('SET_TOKEN', token);<br> // 不在这里重复调 uni.setStorageSync,由 mutation 统一负责<br> }<br> }<br>}) - 首次加载时,state 初始值应从 storage 读取:
token: uni.getStorageSync('token') || '' - 别在
state里放大对象(如用户完整 profile),只存核心字段;大结构用单独 storage key 管理
Pinia 替代方案里 setItem 和 getItem 必须重写
Pinia 的 persist 插件默认走浏览器 API,小程序端必须显式指定 uni 接口,否则初始化就 crash:
- 模块级配置示例:
export const useUserStore = defineStore('user', () => {<br> const token = ref('');<br> return { token };<br>}, {<br> persist: {<br> storage: {<br> getItem(key) { return uni.getStorageSync(key); },<br> setItem(key, value) { uni.setStorageSync(key, value); }<br> }<br> }<br>}); - 全局插件方式(推荐):
pinia.use(createPersistedState({ storage: { getItem: uni.getStorageSync, setItem: uni.setStorageSync } })) - 注意:
uni.getStorageSync返回null而不是undefined,Pinia 默认解析器可能出错,建议加一层兜底:getItem(key) { return uni.getStorageSync(key) ?? null; } - 如果用了 TypeScript,记得给
storage加类型断言,否则 TS 会报setItem参数类型不匹配
onLaunch 里读 storage,但某些分包页面在 store 初始化完成前就执行了 mapState,拿到空值。解决方案不是加延时,而是让 state 初始值自带 fallback,并接受异步更新。


















