微信小程序全局数据共享

一、前言:为什么需要全局数据共享?

你是否遇到过这些问题?

  • 用户登录后,多个页面都要获取 userInfo
  • 主题色切换,所有页面都要响应
  • 购物车商品数量变化,底部 tab 需要实时更新

根本原因小程序页面之间天然隔离,无法直接共享数据

在 Vue 中有 Vuex,React 中有 Context 或 Redux,那小程序有没有优雅的全局状态管理方案

答案是:有!而且不止一种 。本文将为你详解 5 种主流全局数据共享方案,从简单到复杂,助你选择最适合项目的方案。


二、方案 1:App.globalData(最简单)

原理

利用 App 实例的 globalData 属性,作为全局变量容器。

实现步骤

javascript 复制代码
// app.js
App({
  globalData: {
    userInfo: null,
    theme: 'light'
  }
});
javascript 复制代码
// pages/profile/profile.js
const app = getApp();

Page({
  onLoad() {
    // 读取
    console.log(app.globalData.userInfo);
    
    // 修改
    app.globalData.theme = 'dark';
  }
});

✅ 优点

  • 无需额外依赖
  • 上手极快,适合小型项目

❌ 缺点

  • 无响应式更新:修改后页面不会自动刷新
  • 无数据监听:无法知道谁改了数据
  • 易造成命名冲突

📌 适用场景:只读配置、一次性初始化数据(如用户信息)


三、方案 2:Behavior(可复用逻辑 + 数据)

原理

通过 Behavior 封装可复用的状态和方法,被多个页面/组件混入。

实现示例

javascript 复制代码
// behaviors/user-behavior.js
module.exports = Behavior({
  data: {
    userInfo: null
  },
  methods: {
    setUserInfo(user) {
      this.setData({ userInfo: user });
    }
  }
});
javascript 复制代码
// pages/home/home.js
const userBehavior = require('../../behaviors/user-behavior');

Page({
  behaviors: [userBehavior],
  onLoad() {
    this.setUserInfo({ name: '张三' });
  }
});

✅ 优点

  • 逻辑复用,避免重复代码
  • 支持 setData 响应式更新

❌ 缺点

  • 每个页面/组件拥有独立副本,不是真正"全局共享"
  • 无法跨页面同步状态

📌 适用场景 :相同 UI 逻辑复用(如表单验证),非全局状态


四、方案 3:事件总线(Event Bus)------ 推荐!

原理

基于 wx. $ emit / wx. $ on 实现发布-订阅模式,实现跨页面通信。

实现步骤

javascript 复制代码
// utils/event-bus.js
class EventBus {
  constructor() {
    this.events = {};
  }

  on(name, callback) {
    if (!this.events[name]) this.events[name] = [];
    this.events[name].push(callback);
  }

  emit(name, data) {
    if (this.events[name]) {
      this.events[name].forEach(cb => cb(data));
    }
  }

  off(name, callback) {
    if (this.events[name]) {
      const index = this.events[name].indexOf(callback);
      if (index > -1) this.events[name].splice(index, 1);
    }
  }
}

export default new EventBus();
javascript 复制代码
// app.js
import eventBus from './utils/event-bus';
App({ eventBus });
javascript 复制代码
// pages/cart/cart.js
const app = getApp();

Page({
  data: { count: 0 },

  onLoad() {
    // 监听购物车变化
    app.eventBus.on('cartChange', (count) => {
      this.setData({ count });
    });
  },

  onUnload() {
    // 记得取消监听,防止内存泄漏
    app.eventBus.off('cartChange');
  }
});
javascript 复制代码
// pages/goods/goods.js
// 添加商品时触发
getApp().eventBus.emit('cartChange', 5);

✅ 优点

  • 真正跨页面通信
  • 轻量、灵活、解耦
  • 支持多对多通信

❌ 缺点

  • 需手动管理监听/移除
  • 调试困难(事件流不直观)

📌 适用场景:中大型项目,需跨页面状态同步(如购物车、登录态)


五、方案 4:自定义 Store(类 Vuex)

原理

封装一个响应式 Store,支持 statemutationsactions

简易实现

javascript 复制代码
// store/index.js
class Store {
  constructor(options) {
    this.state = options.state;
    this.mutations = options.mutations || {};
    this.subscribers = [];
  }

  commit(mutationName, payload) {
    if (this.mutations[mutationName]) {
      this.mutations[mutationName](this.state, payload);
      this.notify();
    }
  }

  subscribe(callback) {
    this.subscribers.push(callback);
    return () => {
      const index = this.subscribers.indexOf(callback);
      if (index > -1) this.subscribers.splice(index, 1);
    };
  }

  notify() {
    this.subscribers.forEach(cb => cb(this.state));
  }
}

export default new Store({
  state: {
    cartCount: 0,
    userInfo: null
  },
  mutations: {
    SET_CART_COUNT(state, count) {
      state.cartCount = count;
    },
    SET_USER_INFO(state, user) {
      state.userInfo = user;
    }
  }
});
javascript 复制代码
// pages/cart/cart.js
import store from '../../store';

Page({
  data: { count: 0 },

  onLoad() {
    this.unsubscribe = store.subscribe((state) => {
      this.setData({ count: state.cartCount });
    });
  },

  onUnload() {
    this.unsubscribe && this.unsubscribe();
  }
});
javascript 复制代码
// 任意页面修改状态
store.commit('SET_CART_COUNT', 10);

✅ 优点

  • 结构清晰,类似 Vuex
  • 支持响应式更新
  • 易于测试和维护

❌ 缺点

  • 需自行实现(或引入第三方库)
  • 学习成本略高

📌 适用场景:复杂状态管理,追求代码规范性


六、方案 5:使用第三方库(如 miniprogram-store)

如果你不想造轮子,可直接使用社区成熟方案:

安装示例:

bash 复制代码
npm install miniprogram-store --save

然后按文档集成即可,享受开箱即用的响应式体验。


七、五大方案对比总结

方案 响应式 跨页面 复杂度 适用项目规模
globalData 小型 demo
Behavior ❌(独立副本) ⭐⭐ 组件逻辑复用
✅ Event Bus ✅(需手动 setData) ⭐⭐ 中大型项目(推荐)
自定义 Store ⭐⭐⭐ 大型项目
第三方库 ⭐⭐ 追求效率的团队

八、避坑指南

❌ 坑 1:在 globalData 中存大量数据

风险 :主包体积增大,启动变慢
建议:仅存关键标识(如 userId),详情按需加载

❌ 坑 2:忘记移除事件监听

后果 :内存泄漏,页面多次触发
解决 :务必在 onUnloadoffunsubscribe

❌ 坑 3:Store 状态直接修改

错误

javascript 复制代码
store.state.cartCount = 5; // 不会触发更新!

正确

javascript 复制代码
store.commit('SET_CART_COUNT', 5);

九、结语

感谢您的阅读!如果你有任何疑问或想要分享的经验,请在评论区留言交流!

相关推荐
IT观测13 小时前
# 2026年SaaS小程序制作平台对比:乔拓云、有赞、微盟
小程序
宁夏雨科网17 小时前
印刷包装公司开发小程序的优势与内容
小程序·展示小程序·印刷包装·印刷公司小程序
lichenyang4531 天前
从零到一:用 Taro + React 搭建数据采集小程序
react.js·小程序·taro
黄华SJ520it2 天前
139小程序商城模式开发
小程序·软件需求·系统开发
Greg_Zhong2 天前
详细说下小程序中使用canvas的体验
小程序·canvas绘制·canvas绘制内容溢出·绘制内容模拟器不正常·绘制内容真机正常
小羊Yveesss2 天前
2026 多门店小程序如何提升效率?连锁门店降本增效实操指南,数字化转型必看
大数据·小程序
2501_941982052 天前
提高私域转化率:如何通过 API 自动发送小程序卡片?
小程序·机器人·自动化·企业微信·rpa
码视野2 天前
完全开源-支持二开-可做毕业论文-家政服务预约小程序
小程序
码视野2 天前
全开源-健身运动预约小程序 — 从需求到原型的全栈实践
小程序
游戏开发爱好者82 天前
深入理解iOSTime Profiler:提升iOS应用性能的关键工具
android·ios·小程序·https·uni-app·iphone·webview