小程序中全局数据共享

1,496 阅读3分钟

「这是我参与2022首次更文挑战的第28天,活动详情查看:2022首次更文挑战

什么是全局数据共享

全局数据共享(又叫:状态管理)是为了解决组件之间数据共享的问题。开发中常用的全局数据共享方案有:Vues、Redux、MobX等


小程序中的全局数据共享方案

在小程序中,可以使用 mobx-miniprogram 配合 mobx-miniprogram-bindings 实现全局数据共享

  • mobx-miniprogram 用来创建 Store 实例对象
  • mobx-miniprogram-bindings 用来把 Store 中的共享数据或方法,绑定到组件或页面中使用

安装 MobX 相关的包

在项目中运行如下的命令,安装 MobX 相关的包

npm install --save mobx-miniprogram
npm install --save mobx-miniprogram-bindings

注:MobX 相关的包安装完毕之后,记得删除 miniprogram_npm 目录后,重新构建npm


创建 MobX 的 Store 实例

在根目录创建一个 store 文件夹,在该文件夹创建 store.js 文件,在这个 js 文件中,专门来创建 store 的实例对象

//使用属性将 observable 导入
//使用方法将 action 导入
import { action, observable } from 'mobx-miniprogram'

export const store = observable({

  //定义数据字段
  numA: 1,
  numB: 2,

  //定义计算属性
  get sum(){
    return this.numA + this.numB
  },

  //通过 actions 方法,来修改 store 中的数据
  updateNum1: action(function (value) {
    this.numA += value
  }),
  
  updateNum2: action(function (value) {
    this.numB += value
  })
})

将 store 中的成员绑定到页面中

  • 在页面 .js 文件的头部导入需要的方法和实例对象

    import { createStoreBindings } from 'mobx-miniprogram-bindings'
    import { store } from '../../store/store'
    
  • 在页面的 onLoad 生命周期函数中进行绑定的逻辑

    • 第一个参数:表示将 store 中的数据绑定到页面上,this 表示当前页面
    • 第二个参数:是一个配置对象,分别有三个属性,分别是 storefieldsactionsstore 表示数据源,将 store 中的数据绑定到页面上,fields 表示将哪些字段绑定到页面上,actions 表示将哪些方法绑定到页面上
    • 返回值:返回值是为了页面在最后被卸载的时候处理一些清理的逻辑
    onLoad: function (options) {
      this.storeBindings = createStoreBindings(this, {
        store,
        fields: ["numA","numB","sum"],
        actions:["updateNum1"]
      })
    },
    
  • 在页面的 onUnLoad 生命周期函数中进行清理的逻辑

    onUnload: function () {
      this.storeBindings.destroyStoreBindings()
    },
    

在页面上使用 store 中的成员

  • 页面结构(.wxml

    <view>{{numA}} + {{numB}} = {{sum}}</view>
    <van-button type="primary" bindtap="btnHandler1" data-step="{{1}}"> numA + 1 </van-button>
    <van-button type="danger" bindtap="btnHandler1" data-step="{{-1}}"> numA - 1 </van-button>
    
  • 数据结构(.js

    import { action } from 'mobx-miniprogram'
    import { createStoreBindings } from 'mobx-miniprogram-bindings'
    import { store } from '../../store/store'
    
    Page({
      onLoad: function (options) {
        this.storeBindings = createStoreBindings(this, {
          store,
          fields: ["numA","numB","sum"],
          actions:["updateNum1"]
        })
      },
      btnHandler1(e){
        this.updateNum1(e.target.dataset.step)
      },
      onUnload: function () {
        this.storeBindings.destroyStoreBindings()
      }
    })
    
  • 页面实现

    Snip20220214_2.png


将 store 中的成员绑定到组件中

  • 在组件 .js 文件的头部导入需要的方法和实例对象

    import { storeBindingsBehavior } from "mobx-miniprogram-bindings"
    import { store } from "../store/store"
    
  • 通过 storeBindingsBehavior 来实现自动绑定

    Component({
      //创建一个 behaviors 数组,并将 storeBindingsBehavior 放入数组,这样就可以通过 behaviors 实现数据或方法的映射
      behaviors: [storeBindingsBehavior],
    
  • 声明一个配置对象,接收三个属性,分别是 storefieldsactionsstore 表示数据源,fields 表示将哪些字段绑定到组件上,actions 表示将哪些方法绑定到页面上

storeBindings : {
  store,                            //指定数据源
  fields: {
    numA: ()=> store.numA,          //第一种方式
    numB: (store) => store.numB,    //第二种方式
    sum: "sum"                      //第三种方式(冒号右面为 store 中的字段,冒号左边组件中定义的属性)
  },
  actions:{                         //指定要绑定的方法(冒号右面为 store 中的方法名字,冒号左边组件中定义的方法名字)
    updateNum2: "updateNum2"
  }
},

在组件上使用 store 中的成员

  • 页面结构(.wxml

    <view>{{numA}} + {{numB}} = {{sum}}</view>
    <van-button type="primary" bindtap="btnHandler2" data-step="{{1}}"> numB + 1 </van-button>
    <van-button type="danger" bindtap="btnHandler2" data-step="{{-1}}"> numB - 1 </van-button>
    
  • 数据结构(.js

    Component({
      behaviors: [storeBindingsBehavior],
      
      storeBindings : {
        store,
        fields: {
          numA: ()=> store.numA,
          numB: (store) => store.numB,
          sum: "sum"
        },
        actions:{
          updateNum2: "updateNum2"
        }
      },
      
      properties: {
      },
       data: {
      },
    
      methods: {
        btnHandler2(e){
            this.updateNum2(e.target.dataset.step)
        },
      }
    })
    
  • 页面实现

    Snip20220215_3.png