微信小程序全局数据共享

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

你是否遇到过这些问题?

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

九、结语

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

相关推荐
吴声子夜歌16 小时前
小程序——生命周期函数和事件处理函数
服务器·前端·小程序
hnxaoli1 天前
win10程序(十六)通达信参数清洗器
开发语言·python·小程序·股票·炒股
码云数智-大飞1 天前
自助建站系统哪个好?快速建站哪个平台好
微信小程序
吴声子夜歌2 天前
小程序——项目结构
小程序
大黄说说2 天前
微信小程序制作平台有哪些?SaaS小程序搭建平台推荐
微信小程序
Lucky小黄人2 天前
微信小程序查看备案号
微信小程序·小程序
码云数智-园园2 天前
小程序制作平台哪个好?微信小程序制作平台对比评测
微信小程序
毕设源码-郭学长3 天前
【开题答辩全过程】以 基于微信小程序的当当手办店铺为例,包含答辩的问题和答案
微信小程序·小程序
qq_24218863323 天前
微信小程序新年首页源码
微信小程序·小程序
中国胖子风清扬4 天前
GPUI 在 macOS 上编译问题排查指南
spring boot·后端·macos·小程序·rust·uni-app·web app