Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/wechat-miniprogram/mobx-miniprogram-bindings
小程序的 MobX 绑定辅助库
https://github.com/wechat-miniprogram/mobx-miniprogram-bindings
Last synced: 5 days ago
JSON representation
小程序的 MobX 绑定辅助库
- Host: GitHub
- URL: https://github.com/wechat-miniprogram/mobx-miniprogram-bindings
- Owner: wechat-miniprogram
- License: mit
- Created: 2019-08-14T06:15:48.000Z (over 5 years ago)
- Default Branch: master
- Last Pushed: 2024-11-13T04:21:59.000Z (29 days ago)
- Last Synced: 2024-11-29T14:11:42.451Z (13 days ago)
- Language: TypeScript
- Size: 239 KB
- Stars: 210
- Watchers: 12
- Forks: 20
- Open Issues: 3
-
Metadata Files:
- Readme: README.md
- License: LICENSE
Awesome Lists containing this project
- awesome-state - mobx-miniprogram-bindings
README
# 小程序的 MobX 绑定辅助库
小程序的 MobX 绑定辅助库。
> 此 behavior 依赖开发者工具的 npm 构建。具体详情可查阅 [官方 npm 文档](https://developers.weixin.qq.com/miniprogram/dev/devtools/npm.html) 。
## 使用方法
需要小程序基础库版本 >= 2.11.0 的环境。
具体的示例完整代码,可以参考 [examples](./examples/) 。
1. 安装 `mobx-miniprogram` 和 `mobx-miniprogram-bindings` :
```shell
npm install --save mobx-miniprogram mobx-miniprogram-bindings
```2. 创建 MobX Store。
```js
// store.js
import { observable, action } from 'mobx-miniprogram'// 创建 store 时可以采用任何 mobx 的接口风格
// 这里以传统的 observable 风格为例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. 在 Page 或 Component 构造器中使用:
```js
import { storeBindingsBehavior } from 'mobx-miniprogram-bindings'
import { store } from './store'Component({
behaviors: [storeBindingsBehavior], // 添加这个 behavior
data: {
someData: '...',
},
storeBindings: {
store,
fields: {
numA: () => store.numA,
numB: (store) => store.numB,
sum: 'sum',
},
actions: {
buttonTap: 'update',
},
},
methods: {
myMethod() {
this.data.sum // 来自于 MobX store 的字段
},
},
})
```## TypeScript 接口
在 TypeScript 下,可以使用 `ComponentWithStore` 接口。它会自动处理一些类型问题。注意:
* 使用这个接口时,不要在 behaviors 中额外引入 `storeBindingsBehavior` ;
* `fields` 和 `actions` 末尾需要加上 `as const` 以便更好的类型推导;
* `storeBindings` 如果是一个数组,也要在数组后加上 `as const` 。```js
import { ComponentWithStore } from 'mobx-miniprogram-bindings'ComponentWithStore({
data: {
someData: '...',
},
storeBindings: {
store,
fields: ['numA', 'numB', 'sum'] as const,
actions: {
buttonTap: 'update',
} as const,
},
})
````BehaviorWithStore` 接口类似。
```js
import { BehaviorWithStore } from 'mobx-miniprogram-bindings'export const testBehavior = BehaviorWithStore({
storeBindings: {
store,
fields: ['numA', 'numB', 'sum'] as const,
actions: ['update'] as const,
},
})
```目前 TypeScript 接口定义依赖于 `miniprogram-api-typings ^4.0.0` 。
(如使用老版本的 api-typings ,请使用本项目的 v4 或 v3 版本。)## glass-easel Chaining API 接口
使用 glass-easel Chaining API 时,使用 `initStoreBindings` 更友好。
```js
import { initStoreBindings } from 'mobx-miniprogram-bindings'Component()
.init((ctx) => {
const { listener } = ctx
initStoreBindings(ctx, {
store,
fields: ['numA', 'numB', 'sum'],
})
const buttonTap = listener(() => {
store.update()
})
return { buttonTap }
})
.register()
```## 具体接口说明
将页面、自定义组件和 store 绑定有两种方式: **behavior 绑定** 和 **手工绑定** 。
### behavior 绑定
**behavior 绑定** 适用于 `Component` 构造器。做法:使用 `storeBindingsBehavior` 这个 behavior 和 `storeBindings` 定义段。
```js
import { storeBindingsBehavior } from 'mobx-miniprogram-bindings'Component({
behaviors: [storeBindingsBehavior],
storeBindings: {
/* 绑定配置(见下文) */
},
})
```也可以把 `storeBindings` 设置为一个数组,这样可以同时绑定多个 `store` :
```js
import { storeBindingsBehavior } from 'mobx-miniprogram-bindings'Component({
behaviors: [storeBindingsBehavior],
storeBindings: [
{
/* 绑定配置 1 */
},
{
/* 绑定配置 2 */
},
],
})
```### 手工绑定
**手工绑定** 更加灵活,适用于 store 需要在 `onLoad` (自定义组件 attached )时才能确定的情况。
做法:使用 `createStoreBindings` 创建绑定,它会返回一个包含清理函数的对象用于取消绑定。
注意:在页面 onUnload (自定义组件 detached )时一定要调用清理函数,否则将导致内存泄漏!
```js
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](https://github.com/wechat-miniprogram/computed) 时,在 behaviors 列表中 `computedBehavior` 必须在后面:
```js
Component({
behaviors: [storeBindingsBehavior, computedBehavior],
/* ... */
})
```### 关于部分更新
如果只是更新对象中的一部分(子字段),是不会引发界面变化的!例如:
```js
Component({
behaviors: [storeBindingsBehavior],
storeBindings: {
store,
fields: ['someObject'],
},
})
```如果尝试在 `store` 中:
```js
this.someObject.someField = 'xxx'
```这样是不会触发界面更新的。请考虑改成:
```js
this.someObject = Object.assign({}, this.someObject, { someField: 'xxx' })
```