微信小程序中组件传参(六):mobx-miniprogram状态管理工具 跨组件通信

388 阅读4分钟

mobx-miniprogram

小程序官方的状态管理工具,类似于vuex、pinia。官方文档

  • npm install mobx-miniprogram mobx-miniprogram-bindings --save :下载mobx-miniprogram和mobx-miniprogram-bindings。

创建Store对象

observable

  • 用于创建一个被检测的对象,对象的属性就是应用的状态(state) 如:numA: 0,obj1: {age:18},这些状态会被转换成响应式数据。
  • 需要通过import {observable} from 'mobx-miniprogram'导入observable。
import {observable} from 'mobx-miniprogram'
const numstore = observable({
  numA: 0,
  obj1: {name: 'tzof',age: 18},
  arr1: [1,2,3],
})

action

  • 用于修改状态(state)的方法,需要使用action函数显式的声明创建。
  • 使用方式自定义函数名: action(function(){this.numA += 1})
  • 在回调的方法中如果需要获取应用的状态可以使用this.获取。
  • 注意: action中不能使用箭头函数()=>{}因为箭头函数指向触发这个方法的位置也就是page页面或者component组件,只有this指向observable对象才能获取到状态。
  • 需要通过import {action} from 'mobx-miniprogram'导入action。
import {action} from 'mobx-miniprogram'
const numstore = observable({
  numA: 0,
  update: action(function () {
    this.numA += 1;
  }),
})

computed

  • 根据已有状态(state)生成新的值。计算属性是一个自定义方法,在方法前面必须加上get修饰符。
  • 使用方式get 自定义函数名(){return this.numA + this.numA}。必须return返回。
  • 计算属性也算一个状态(state)可以直接调用。
const numstore = observable({
  numA: 0,
  get sum() {
    return this.numA + this.numB;
  }
})

构造方法

Page默认构造方法,createStoreBindings手工绑定(Component也可用)

  • 通过import {createStoreBindings} from 'mobx-miniprogram-bindings'导入。
  • createStoreBindings创建绑定,PageonLoadComponentattached生命周期内用。
    createStoreBindings(this, {同storeBindings内的配置})参数一传递this,参数二store配置。
    注意无法使用数组形式创建多个store,只能使用多个createStoreBindings创建。
  • this.storeBindings = createStoreBindings(this,{...})赋值给一个变量它会返回一个包含清理函数的对象用于取消绑定。
  • this.storeBindings.destroyStoreBindings()调用清理函数,PageonUnloadComponentdetached生命周期内使用清理函数,一定要调用清理函数,否则将导致内存泄漏!
  • 使用createStoreBindings方法绑定store,数据会被注入到data中,方法会被注入到Page第一层结构中。
import {createStoreBindings} from 'mobx-miniprogram-bindings'
import userStores from '../../stores/user'
Page({
  data: {
    storeBindings: {},
  },
  onLoad(){
    this.data.storeBindings = createStoreBindings(this, {
      store: userStores,
      fields: ['token', 'openId', 'userinfo'],
      actions: ['setToken', 'setOpenId', 'setUserinfo'],
    })
  },
  onUnload(){
    this.data.storeBindings.destroyStoreBindings();
  },
})

Component默认构造方法,behaviors导入storeBindingsBehavior

  • 通过import {storeBindingsBehavior} from 'mobx-miniprogram-bindings'导入storeBindingsBehavior。
  • 在组件的behaviors中导入storeBindingsBehavior方法。behaviors: [storeBindingsBehavior]
  • 使用storeBindings绑定store,数据会被注入到data中,方法会被注入到methods中。
import {storeBindingsBehavior} from 'mobx-miniprogram-bindings'
import numstore from '../..//stores/numstore'
Component({
  behaviors: [storeBindingsBehavior],
  storeBindings: {
    store: numstore,
    fields: ['numA', 'numB', 'sum'],
    actions: ['update'],
  },
  data: {name: 'tzof'},
  methods: {
    testFun(){console.log('111')}
  },
})

ComponentWithStore构造方法

  • 通过import {ComponentWithStore} from 'mobx-miniprogram-bindings'导入ComponentWithStore方法。
  • 将原先的Component替换为ComponentWithStore构造方法。
  • 使用storeBindings绑定store,数据会被注入到data中,方法会被注入到methods中。
import {ComponentWithStore} from 'mobx-miniprogram-bindings'
import numstore from '../..//stores/numstore'
ComponentWithStore({
  storeBindings: {
    store: numstore,
    fields: ['numA', 'numB', 'sum'],
    actions: ['update'],
  },
  data: {name: 'tzof'},
  methods: {
    testFun(){console.log('111')}
  },
})

storeBindings

storeBindings用来配置当前组件需要与哪些store进行关联。

  • 单个store实例使用方式storeBindings:{}
  • 多个store实例使用方式storeBindings:[{},{}]。数组的每个元素都是一个单独的store对象。
import {ComponentWithStore} from 'mobx-miniprogram-bindings'
import numstore from '../..//stores/numstore'
import stores from '../..//stores/stores'
ComponentWithStore({
  // 单个
  storeBindings: {store: numstore},
  // 多个
  storeBindings: [
    {store: numstore},
    {store: stores},
  ], 
})

store

  • 需要用到的store实例。需要使用import导入用到的store实例。
import {ComponentWithStore} from 'mobx-miniprogram-bindings'
import numstore from '../..//stores/numstore'
ComponentWithStore({storeBindings: {store: numstore}})

fields

  • 里面填写对应store实例中需要用的数据,注意使用''包裹,包括计算属性,会被注入到data中。
  • fields 数组写法fields: ['numA', 'numB', 'sum']
  • fields 对象写法 映射fields: {numOne: 'numA',numB: 'numB',sum: 'sum'}映射写法key可以自定义。
  • fields 对象写法 函数fields: {numA: () => numstore.numA}函数写法key可以自定义,value:函数 在函数内部需要返回对应store实例里数据的值。
import {ComponentWithStore} from 'mobx-miniprogram-bindings'
import numstore from '../..//stores/numstore'
ComponentWithStore({
  storeBindings: {
    store: numstore, 
    // 数组写法
    fields: ['numA', 'numB', 'sum'],
    // 对象写法
    // 映射
    fields: {
      numA: 'numA',
      numBTwo, 'numB',
      sum: 'sum'
    },
    // 函数 对应store实例里数据的值。
    fields: {
      numATwo: () => numstore.numA,
      numB: () => numstore.numB,
      sum: () => numstore.sum,
    }
  }
})

actions

  • 需要用到的action方法,注意使用''包裹,会被注入到methods中。
  • actions 数组写法actions: ['update']
  • actions 对象写法actions: { updateTwo: 'update'}。key可以自定义。
import {ComponentWithStore} from 'mobx-miniprogram-bindings'
import numstore from '../..//stores/numstore'
ComponentWithStore({
  storeBindings: {
    store: numstore,
    // 数组写法
    actions: ['update'],
    // 对象写法
    actions: {
      updateTwo: 'update'
    },
  }
})

namespace命名空间

解决storeBindings数组写法时多个store对象实例有相同fields变量名的问题。

  • namespace只对fields数据生效
  • 页面使用命名空间里的数据时候需要对应namespace名字.数据使用。如{{twoStore.numA}}
import {ComponentWithStore} from 'mobx-miniprogram-bindings'
import numstore from '../..//stores/numstore'
import stores from '../..//stores/stores'
ComponentWithStore({
  storeBindings: [{
     store: numstore,
     fields: ['numA', 'numB', 'sum'], // 页面中使用{{numA}}、{{numB}}、{{sum}}
    }, {
     store: stores,
     namespace: 'twoStore', // 页面使用命名空间里的数据时候需要对应namespace名字.数据使用
     fields: ['numA', 'numB', 'sum'], // 页面中使用{{twoStore.numA}}、{{twoStore.numB}}、{{twoStore.sum}}
    }, 
  ]
})