真正能跨平台、可维护、不踩坑的全局变量方案只有两个:用 globalData 存只读轻量数据(如 token、用户昵称),或用 Vuex 管理响应式状态(如购物车、登录态联动)。
别挂 vue.prototype,也别只靠 uni.setstoragesync,真正能跨平台、可维护、不踩坑的全局变量方案只有两个:用 globaldata 存只读轻量数据(如 token、用户昵称),或用 vuex 管理响应式状态(如购物车、登录态联动)。其他方式要么失效,要么埋雷。
为什么 Vue.prototype.$xxx 在小程序里不生效
小程序端的 Vue 实例不是标准 Vue runtime,Vue.prototype 注入后不会被分包页面、nvue 页面或某些条件编译分支识别。H5 端虽能跑通,但会丢失响应式追踪、TypeScript 类型推导,且和 Vue 3 的 Composition API 设计冲突。更隐蔽的问题是:this.$root.xxx 在分包 tabbar 页面中指向的是各自独立的根实例,根本不是“全局”。
常见错误现象:
- 登录后在 A 页面设了
this.$root.token = 'abc',B 页面读出来仍是undefined - TS 报错
Property 'token' does not exist on type 'CombinedVueInstance' - APP 端正常,微信小程序白屏或 setData 警告
getApp().globalData 怎么安全初始化和读写
这是 uni-app 唯一原生跨平台(H5 / 小程序 / APP)的全局对象,本质是小程序 App 实例的属性,nvue 和 vue 页面都能访问,且不受分包加载影响。
实操建议:
- 初始化必须放在
App.vue的onLaunch或onShow中,不能在created钩子——小程序端生命周期早于 Vue 实例创建 - 只存简单值:
String、Number、Boolean、扁平对象;避免放Date、RegExp、Function,否则 H5 端可能序列化失败 - 修改后视图不自动更新,需手动触发:
this.$forceUpdate(),或配合watch+computed模拟响应式 - 示例写法:
onLaunch() { const app = getApp() app.globalData = { token: '', userInfo: null, apiBase: 'https://api.example.com' } }
Vuex 在 uni-app 中必须手动挂载
uni-app 不会自动把 store 挂到所有组件的 this.$store 上,尤其分包页面里 this.$store 是 undefined。必须显式处理。
关键步骤:
- 在
/store/index.js导出一个单例new Vuex.Store({}),不要导出函数(避免多次 new) - 在
main.js中执行Vue.prototype.$store = store(H5/APP 有效),但小程序端仍需额外处理 - 每个用到 store 的页面,必须显式
import store from '@/store',然后直接调用store.state.xxx或store.dispatch('xxx') - 小程序端 state 里禁止存不可序列化值,否则
setData时触发警告甚至白屏 - TypeScript 下务必给
store添加类型定义,否则store.state.user.name无法推导
混用 globalData 和 Vuex 时最常漏掉的同步点
典型场景:登录成功后,你把 token 写进了 store.state.auth.token,却忘了同步到 getApp().globalData.token。结果后续 API 请求头从 globalData 取 token,拿到空值,401 报错。
这不是设计缺陷,而是人为疏忽。只要用了双源,就必须统一入口更新:
- 所有 token 更新操作,必须同时调用
store.commit('SET_TOKEN', val)和getApp().globalData.token = val - 推荐封装一个
setAuth(token)工具函数,收口所有写入逻辑 - 不要依赖 “Vuex 改了,globalData 自动跟着变”——它俩内存地址完全独立
真正难的不是怎么设,而是怎么让不同机制下的变量始终对齐。这点一旦忽略,调试成本远高于初期多写几行同步代码。


















