微信小程序全局数据共享

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

你是否遇到过这些问题?

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

九、结语

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

相关推荐
桐溪漂流5 小时前
微信小程序cli脚本预览上传
微信小程序·小程序
咖啡の猫5 小时前
微信小程序使用 npm 包
微信小程序·小程序·npm
说私域5 小时前
开源链动2+1模式商城小程序的营销技术与私域运营策略研究
人工智能·小程序·开源·流量运营·私域运营
小小王app小程序开发19 小时前
淘宝扭蛋机小程序核心玩法拆解与技术运营分析
大数据·小程序
说私域1 天前
AI智能名片商城小程序数据清洗的持续运营策略与实践研究
大数据·人工智能·小程序·流量运营·私域运营
东东5161 天前
xxx食堂移动预约点餐系统 (springboot+微信小程序)
spring boot·微信小程序·小程序·毕业设计·个人开发·毕设
CHU7290351 天前
一番赏盲盒抽卡机小程序:解锁惊喜体验与社交乐趣的多元功能设计
前端·小程序·php
2501_915918411 天前
HTTPS 代理失效,启用双向认证(mTLS)的 iOS 应用网络怎么抓包调试
android·网络·ios·小程序·https·uni-app·iphone
数字游民95271 天前
半年时间大概上了70个web站和小程序,累计提示词超过20w
人工智能·ai·小程序·vibecoding·数字游民9527