微信小程序全局数据共享

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

你是否遇到过这些问题?

  • 用户登录后,多个页面都要获取 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);

九、结语

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

相关推荐
蜗牛前端2 天前
codex 全流程开发上线的高颜值礼簿小程序
前端·微信小程序
爱勇宝6 天前
我想认真做一件小事:让孩子和家长更好地互动
微信小程序·小程序·云开发
唯火锅不可辜负6 天前
避坑指南:iOS 下 scroll-view 嵌套 fixed 布局的“翻车”现场与修复
微信小程序
didiplus6 天前
运维人的随身神器:我把25个常用工具塞进了微信小程序
微信小程序
一份执念7 天前
uni-app 小程序分包限制处理与主包体积优化实战
前端·微信小程序
一份执念7 天前
ECharts 安装与使用完全指南:从全量引入到小程序分包优化
微信小程序·echarts
skiyee8 天前
🔥UniApp 仅需 5 行代码!实现所有页面中控制应用主题变化
前端·微信小程序
Jinkey9 天前
要用户手机号真的是为了打骚扰电话吗?浅谈微信生态会员账号体系与资产合并
后端·微信·微信小程序
用户43242810611411 天前
微信小程序从0到1接入微信支付的完整攻略
微信小程序
spmcor13 天前
微信小程序 setStorageSync 踩坑实录:别让"顺手一存"变成"隐形炸弹"
微信小程序