globalData 是 uni-app 中唯一支持 vue 和 nvue 页面双向共享数据的机制,但非响应式,需手动更新;仅适合存配置、token 等低频变更数据,不可用于状态同步。

globalData 是 uni-app 中唯一原生支持 vue 和 nvue 页面双向共享数据的机制,但它的行为和 Vue 响应式系统不联动——改了值,页面不会自动更新。
为什么 globalData 不能直接响应式更新
因为 App.vue 中的 globalData 是一个普通对象属性,不是通过 data() 或 ref/reactive 定义的。uni-app 没有对它做响应式代理,所以即使你写 getApp().globalData.count = 100,已渲染的页面里绑定的 {{ $scope.globalData.count }} 不会重绘。
常见错误现象:onLoad 里读到旧值、watch 监听不到变化、子组件 computed 不触发更新。
- 必须手动触发更新:用
this.$forceUpdate()或重赋值给响应式字段(如this.localCount = getApp().globalData.count) - 避免在
globalData里存嵌套深的对象或数组——浅层赋值才可靠 - 不要依赖
globalData实现跨页“状态同步”,它只适合存配置、token、用户基础信息等低频变更数据
如何安全地在 App.vue 中定义 globalData
必须写在 App.vue 的 export default 对象顶层,不能放在 data()、onLaunch 或其他生命周期内。
export default {
// ✅ 正确:顶层属性
globalData: {
token: '',
userInfo: null,
theme: 'light'
},
onLaunch() {
// ❌ 这里改 globalData 不生效(此时实例还没挂载)
this.globalData.token = 'xxx'
},
onShow() {
// ✅ 可以在这里初始化,但需确保 this 已指向 App 实例
if (!this.globalData.token) {
this.globalData.token = uni.getStorageSync('token') || ''
}
}
}
注意:globalData 在 H5 端是单例,在小程序端每个 WebView 是独立副本(但同一小程序进程内共享),所以不要假设它跨进程持久。
在页面中读写 globalData 的正确姿势
所有页面都必须通过 getApp() 获取 App 实例,再访问 .globalData。不能用 this.$root.globalData(H5 可能报错,小程序不保证存在)。
- 读取:直接
const app = getApp(); console.log(app.globalData.token) - 写入:必须用
app.globalData.xxx = value,不能解构赋值(const { token } = app.globalData; token = 'new'无效) - 类型安全:建议在
App.vue的globalData上加 JSDoc 注释,或配合 TypeScript interface 声明 - 初始化时机:首次使用前检查是否为
null或undefined,避免Cannot read property 'xxx' of null
globalData 和其他全局方案的关键区别
它和 Vue.prototype、store、provide/inject 不是替代关系,而是互补定位:
-
Vue.prototype:仅限vue页面,无响应式,易命名冲突,适合工具函数(如this.$toast) -
vuex / pinia:响应式强,适合业务状态流,但nvue页面无法直接使用(需额外桥接) -
provide/inject:Vue3 推荐,但只在父子组件链有效,无法跨 TabBar 页面或从 App.vue 向任意页面广播 -
globalData:唯一能被vue和nvue同时读写的“公共内存区”,但仅适合静态/半静态数据
真正容易被忽略的是:当你的页面同时包含 vue 和 nvue(比如首页用 nvue 做动画,详情页用 vue),globalData 是目前最轻量且不失效的通信通道;但如果你需要实时同步登录态变更,就得搭配 uni.$on/uni.$emit 手动通知,或者换用 mobx-miniprogram 这类专为小程序优化的状态库。


















