1、mobx-miniprogram
1.1 介绍
mobx-miniprogram
是针对微信小程序开发的一个简单、高效、轻量级状态管理库,它基于Mobx状态管理框架实现。
使用 mobx-miniprogram 定义管理的状态是响应式的,当状态一旦它改变,所有关联组件都会自动更新相对应的数据
通过该扩展工具库,开发者可以很方便地在小程序中全局共享的状态,并自动更新视图组件,从而提升小程序的开发效率
需要注意:在使用 mobx-miniprogram 需要安装两个包:
mobx-miniprogram
和mobx-miniprogram-bindings
mobx-miniprogram
的作用:创建 Store 对象,用于存储应用的数据mobx-miniprogram-bindings
的作用:将状态和组件、页面进行绑定关联,从而在组件和页面中操作数据- mobx-miniprogram
- mobx-miniprogram-bindings
1.2 使用
1.2.1 创建 Store 对象
如果需要创建 Store
对象需要使用 mobx-miniprogram
,因此需要先熟悉 mobx-miniprogram 三个核心概念:
observable
:用于创建一个被监测的对象,对象的属性就是应用的状态(state),这些状态会被转换成响应式数据。action
:用于修改状态(state)的方法,需要使用 action 函数显式的声明创建。computed
:根据已有状态(state)生成的新值。计算属性是一个方法,在方法前面必须加上 get 修饰符
mobx-miniprogram
详细的使用步骤如下:
- 在项目的根目录下创建
store
文件夹,然后在该文件夹下新建index.js
- 在
/store/index.js
导入observable
、action
方法 - 使用
observable
方法需要接受一个store
对象,存储应用的状态
// observable:用于创建一个被监测的对象,对象的属性就是应用的状态(state), 这些状态会被转换成响应式数据。 // action:用于显式的声明创建更新 state 状态的方法 import { observable, action } from 'mobx-miniprogram' // 使用 observable 创建一个被监测的对象 export const numStore = observable({ // 创建应用状态 numA: 1, numB: 2, // 使用 action 更新 numA 以及 numB update: action(function () { this.numA+=1 this.numB+=1 }), // 计算属性,使用 get 修饰符, get sum() { return this.numA + this.numB; } })
1.2.2 在组件中使用数据
如果需要 Page
或者 Component
中对共享的数据进行读取、更新操作,需要使用 mobx-miniprogram-bindings
mobx-miniprogram-bindings
的作用就是将 Store
和 页面或组件进行绑定关联
- 如果需要在组件中使用状态,需要
mobx-miniprogram-bindings
库中导入ComponentWithStore
方法 - 在使用时:需要将
Component
方法替换成ComponentWithStore
方法 ,原本组件配置项也需要写到该方法中
使用步骤:
- 从
mobx-miniprogram-bindings
库中导入ComponentWithStore
方法 - 将
Component
方法替换成ComponentWithStore
方法 - 然后配置
storeBindings
从Store
中映射数据和方法即可
在替换以后,就会新增一个 storeBindings
配置项,配置项常用的属性有以下三个:
store
: 指定要绑定的 Store 对象fields
: 指定需要绑定的 data 字段actions
: 指定需要映射的 actions 方法
导入的数据会同步到组件的 data 中
导入的方法会同步到组件的 methods 中
// components/custom01/custom01.js import { ComponentWithStore } from 'mobx-miniprogram-bindings' import { numStore } from '../../stores/numstore' ComponentWithStore({ data: { someData: '...' }, storeBindings: { store: numStore, fields: ['numA', 'numB', 'sum'], actions: ['update'] } })
1.2.3 在页面中使用数据
我们可以使用 Component方法构建页面
,然后使用 ComponentWithStore
方法让页面和 Store 建立了关联
如果不想使用 Component 方法构建页面。这时候需要使用 mobx-miniprogram-bindings
提供的 BehaviorWithStore
方法来和 Store 建立关联
使用步骤如下:
- 新建
behavior
文件,从mobx-miniprogram-bindings
库中导入BehaviorWithStore
方法 - 在
BehaviorWithStore
方法中配置storeBindings
配置项从 Store 中映射数据和方法 - 在
Page
方法中导入创建的behavior
,然后配置behavior
属性,并使用导入的behavior
声明。具体内容可以查看behaviors代码复用
// behavior.js import { BehaviorWithStore } from 'mobx-miniprogram-bindings' import { numStore } from '../../stores/numstore' export const indexBehavior = BehaviorWithStore({ storeBindings: { store: numStore, fields: ['numA', 'numB', 'sum'], actions: ['update'], } })
// 页面.js import { indexBehavior } from './behavior' Page({ behaviors: [indexBehavior] // 其他配置项 })
1.2.4 fields、actions 对象写法
import { ComponentWithStore } from 'mobx-miniprogram-bindings' import { numStore } from '../../stores/numstore' ComponentWithStore({ data: { someData: '...' }, storeBindings: { store: numStore, fields: { // 使用函数方式获取 Store 中的数据 a: () => store.numA, b: () => store.numB, // 使用映射形式获取 Store 中的数据,值为数据在 store 中对应的名字 total: 'sub' }, // 使用映射形式获取 Store 中的 action 名字 actions: { // key 自定义,为当前组件中调用的方法 // 值为 store 中对应的 action 名字 buttonTap: 'update' } } })
1.2.5 绑定多个 store 以及命名空间
// behavior.js import { BehaviorWithStore } from 'mobx-miniprogram-bindings' import { numStore } from '../../stores/numstore' export const indexBehavior = BehaviorWithStore({ storeBindings: [ { namespace: 'numStore', store: numStore, fields: ['numA', 'numB', 'sum'], actions: ['update'], }, { // 另一个store } ] })
// index/index.wxml <view>{{ numStore.numA }} + {{ numStore.numB }} = {{numStore.sum}}</view>
2、miniprogram-computed
小程序框架没有提供计算属性相关的 api ,但是官方为开发者提供了拓展工具库 miniprogram-computed。
该工具库提供了两个功能:
- 计算属性
computed
- 监听器
watch
使用方法:
- 如果需要在组件中使用计算属性功能,需要
miniprogram-computed
库中导入ComponentWithComputed
方法。 - 在使用时,需要将
Component
方法替换成ComponentWithComputed
方法 ,原本组件配置项也需要写到该方法中。 - 在替换以后,就可以新增
computed
以及watch
配置项。
2.1 计算属性 computed
computed
函数中不能访问this
,但是提供了形参
,代表data
对象- 计算属性函数的返回值会被设置到
this.data.sum
字段中
// 引入 miniprogram-computed import { ComponentWithComputed } from 'miniprogram-computed' ComponentWithComputed({ data: { a: 1, b: 1 }, computed: { total(data) { // 注意: // computed 函数中不能访问 this ,只有 data 对象可供访问 // 这个函数的返回值会被设置到 this.data.sum 字段中 // 计算属性具有缓存,计算属性使用多次,但是计算属性方法只会执行一次 console.log('~~~~~') return data.a + data.b } } })
2.2 监听器 watch
// 引入 miniprogram-computed import { ComponentWithComputed } from 'miniprogram-computed' ComponentWithComputed({ data: { a: 1, b: 1 }, watch: { //key:需要监听的数据 //value:是回调函数,回调函数有一个形参,形参就是最新的、改变后的数据 a:function(a){ console.log(a) } // 同时对 a 和 b 进行监听 'a, b': function (a, b) { this.setData({ total: a + b }) } } })
3、Mobx 和 Computed 结合使用
- 两个框架扩展提供的
ComponentWithStore
与ComponentWithComputed
方法无法t同时结合使用。
解决方案:
- 使用旧版 API(全部都是用旧的api写)
- 自定义组件仍然使用 Component 方法构建组件,将两个扩展依赖包的使用全部改为旧版 API
- 即添加
computedBehavior
或storeBindingsBehavior
- mobx-miniprogram-bindings
- miniprogram-computed
- 使用兼容写法:(取其中一个写成旧api就行了,另一个照常写就行了)
兼容写法:
import { ComponentWithComputed } from 'miniprogram-computed' // 旧版 API const computedBehavior = require('miniprogram-computed').behavior ComponentWithStore({ behaviors: [computedBehavior],// 添加这个 behavior data: { a: 1, b: 1, sum: 2 }, watch: { 'a, b': function (a, b) { this.setData({ total: a + b }) } }, computed: { total(data) { // 注意: computed 函数中不能访问 this ,只有 data 对象可供访问 // 这个函数的返回值会被设置到 this.data.sum 字段中 return data.a + data.b + data.sum // data.c 为自定义 behavior 数据段 } }, // 实现组件和 Store 的关联 storeBindings: { store: numStore, // fields 和 actions 有两种写法:数组写法 和 对象写法 // 数组写法 fields: ['numA', 'numB', 'sum'], actions: ['update'] } })