官方文档:小程序的 MobX 绑定辅助库
一、使用方法
1. 安装
安装 mobx-miniprogram
和 mobx-miniprogram-bindings
:
npm install --save mobx-miniprogram mobx-miniprogram-bindings
2. 创建 MobX Store
// store.js
import { observable, action } from "mobx-miniprogram";
export const store = observable({
// 数据字段
numA: 1,
numB: 2,
// 计算属性
get sum() {
return this.numA + this.numB;
},
// actions
update: action(function () {
const sum = this.sum;
this.numA = this.numB;
this.numB = sum;
}),
});
3. 使用
在 Component 构造器中使用——behavior 绑定
import { storeBindingsBehavior } from "mobx-miniprogram-bindings";
import { store } from "./store";
Component({
behaviors: [storeBindingsBehavior],
data: {
someData: "...",
},
storeBindings: {
store,
// 方式一:数组形式
// fields: ['numA', 'numB', 'sum'], // --> this.data.numA访问store里面的numA
// 方式二:普通对象键值对形式
// fields: {a: 'numA', b: 'numB', sum: 'sum'}, // this.data.a访问store里面的numA
// 方式三:函数形式
fields: { // fields里面的属性相当于data里面的属性
numA: () => store.numA,
numB: (store) => store.numB,
sum: "sum",
},
// 方式一:数组形式
// actions: ['update'], --> this.update()调用store里面的update
// 方式二:对象形式
actions: { // actions里面的属性相当于methods里面的方法
buttonTap: "update", // --> this.buttonTap()调用store里面的update
},
},
methods: {
myMethod() {
this.data.sum; // 来自于 MobX store 的字段
},
},
});
在 Page 构造器中使用——手工绑定
import { createStoreBindings } from "mobx-miniprogram-bindings";
import { store } from "./store";
Page({
data: {
someData: "...",
},
onLoad() {
this.storeBindings = createStoreBindings(this, {
store,
fields: ["numA", "numB", "sum"],
actions: ["update"],
});
},
onUnload() {
this.storeBindings.destroyStoreBindings();
},
myMethod() {
this.data.sum; // 来自于 MobX store 的字段
},
});
二、两种绑定方式
将页面、自定义组件和 store 绑定有两种方式: behavior 绑定 和 手工绑定 。
behavior 绑定——适用于组件
behavior 绑定 适用于 Component
构造器。做法:使用 storeBindingsBehavior
这个 behavior 和 storeBindings
定义段。
(注意:你可以用 Component
构造器构造页面, 参考文档 。)
import { storeBindingsBehavior } from "mobx-miniprogram-bindings";
Component({
behaviors: [storeBindingsBehavior],
storeBindings: {
/* 绑定配置(见下文) */
},
});
也可以把 storeBindings 设置为一个数组,这样可以同时绑定多个 store :
import { storeBindingsBehavior } from "mobx-miniprogram-bindings";
Component({
behaviors: [storeBindingsBehavior],
storeBindings: [
{
/* store1绑定配置 */
},
{
/* store2绑定配置 */
},
],
});
手工绑定——适用于所有
手工绑定 适用于全部场景。做法:使用 createStoreBindings 创建绑定,它会返回一个包含清理函数的对象用于取消绑定。
注意:在页面 onUnload (自定义组件 detached )时一定要调用清理函数,否则将导致内存泄漏!
import { createStoreBindings } from "mobx-miniprogram-bindings";
Page({
onLoad() {
this.storeBindings = createStoreBindings(this, {
/* 绑定配置(见下文) */
});
},
onUnload() {
this.storeBindings.destroyStoreBindings();
},
});
绑定配置
无论使用哪种绑定方式,都必须提供一个绑定配置对象。这个对象包含的字段如下:
字段名 | 类型 | 含义 |
---|---|---|
store | 一个 MobX observable | 默认的 MobX store |
fields | 数组或者对象 | 用于指定需要绑定的 data 字段 |
actions | 数组或者对象 | 用于指定需要映射的 actions |
fields
fields
有三种形式:
- 数组形式:指定 data 中哪些字段来源于
store
。例如['numA', 'numB', 'sum']
。 - 映射形式:指定 data 中哪些字段来源于
store
以及它们在store
中对应的名字。例如{ a: 'numA', b: 'numB' }
,此时this.data.a === store.numA
this.data.b === store.numB
。 - 函数形式:指定 data 中每个字段的计算方法。例如
{ a: () => store.numA, b: () => anotherStore.numB }
,此时this.data.a === store.numA
this.data.b === anotherStore.numB
。
上述三种形式中,映射形式和函数形式可以在一个配置中同时使用。
如果仅使用了函数形式,那么 store
字段可以为空,否则 store
字段必填。
actions
actions
可以用于将 store 中的一些 actions 放入页面或自定义组件的 this 下,来方便触发一些 actions 。有两种形式:
- 数组形式:例如
['update']
,此时this.update === store.update
。 - 映射形式:例如
{ buttonTap: 'update' }
,此时this.buttonTap === store.update
。
只要 actions
不为空,则 store
字段必填。
三、注意事项
延迟更新与立刻更新
为了提升性能,在 store 中的字段被更新后,并不会立刻同步更新到 this.data
上,而是等到下个 wx.nextTick
调用时才更新。(这样可以显著减少 setData 的调用次数。)
如果需要立刻更新,可以调用:
-
this.updateStoreBindings()
(在 behavior 绑定 中) -
this.storeBindings.updateStoreBindings()
(在 手工绑定 中)
与 miniprogram-computed 一起使用
与 miniprogram-computed 时,在 behaviors 列表中 computedBehavior
必须在后面:
Component({
behaviors: [storeBindingsBehavior, computedBehavior],
/* ... */
});
关于部分更新
如果只是更新对象中的一部分(子字段),是不会引发界面变化的!例如:
Component({
behaviors: [storeBindingsBehavior],
storeBindings: {
store,
fields: ["someObject"],
},
});
如果尝试在 store
中:
this.someObject.someField = "xxx";
这样是不会触发界面更新的。请考虑改成:
this.someObject = Object.assign({}, this.someObject, { someField: "xxx" });
关于store数据修改
- 对于在页面和组件里拿到的store数据,可以跟修改data里面的数据一样修改,例如:
this.storeBindings = createStoreBindings(this, {
store,
fields: ["obj"],
actions: ["update"],
});
setData进行修改:
this.setData({
'obj.name': 'ken'
})
- 对于需要在页面和组件间共享的store数据,需要调actions里面的方法修改,例如:
// store.js
import { observable, action } from "mobx-miniprogram";
export const store = observable({
// 数据字段
account: '1',
// 计算属性
// get sum() {
// return this.numA + this.numB;
// },
// actions
update: action(function (val) {
this.account = val
}),
});
// 页面或组件中
handleTap() {
this.update('xxx')
}
网友评论