{"id":13511383,"url":"https://github.com/wechat-miniprogram/mobx-miniprogram-bindings","last_synced_at":"2025-05-16T01:04:11.200Z","repository":{"id":41557076,"uuid":"202286683","full_name":"wechat-miniprogram/mobx-miniprogram-bindings","owner":"wechat-miniprogram","description":"小程序的 MobX 绑定辅助库","archived":false,"fork":false,"pushed_at":"2025-04-17T07:18:55.000Z","size":252,"stargazers_count":219,"open_issues_count":5,"forks_count":23,"subscribers_count":11,"default_branch":"master","last_synced_at":"2025-04-17T22:11:30.681Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wechat-miniprogram.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-08-14T06:15:48.000Z","updated_at":"2025-04-17T07:18:58.000Z","dependencies_parsed_at":"2024-01-13T19:22:03.675Z","dependency_job_id":"7a3a94d0-460d-4712-99d0-8ffea1128d01","html_url":"https://github.com/wechat-miniprogram/mobx-miniprogram-bindings","commit_stats":{"total_commits":56,"total_committers":5,"mean_commits":11.2,"dds":0.625,"last_synced_commit":"00fb318eb6d8f2b240d89fe81bdb06749746f4d0"},"previous_names":[],"tags_count":9,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wechat-miniprogram%2Fmobx-miniprogram-bindings","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wechat-miniprogram%2Fmobx-miniprogram-bindings/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wechat-miniprogram%2Fmobx-miniprogram-bindings/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wechat-miniprogram%2Fmobx-miniprogram-bindings/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wechat-miniprogram","download_url":"https://codeload.github.com/wechat-miniprogram/mobx-miniprogram-bindings/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254448579,"owners_count":22072764,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-01T03:00:48.865Z","updated_at":"2025-05-16T01:04:11.140Z","avatar_url":"https://github.com/wechat-miniprogram.png","language":"TypeScript","readme":"# 小程序的 MobX 绑定辅助库\n\n小程序的 MobX 绑定辅助库。\n\n\u003e 此 behavior 依赖开发者工具的 npm 构建。具体详情可查阅 [官方 npm 文档](https://developers.weixin.qq.com/miniprogram/dev/devtools/npm.html) 。\n\n## 使用方法\n\n需要小程序基础库版本 \u003e= 2.11.0 的环境。\n\n具体的示例完整代码，可以参考 [examples](./examples/) 。\n\n1. 安装 `mobx-miniprogram` 和 `mobx-miniprogram-bindings` ：\n\n```shell\nnpm install --save mobx-miniprogram mobx-miniprogram-bindings\n```\n\n2. 创建 MobX Store。\n\n```js\n// store.js\nimport { observable, action } from 'mobx-miniprogram'\n\n// 创建 store 时可以采用任何 mobx 的接口风格\n// 这里以传统的 observable 风格为例\n\nexport const store = observable({\n  // 数据字段\n  numA: 1,\n  numB: 2,\n\n  // 计算属性\n  get sum() {\n    return this.numA + this.numB\n  },\n\n  // actions\n  update: action(function () {\n    const sum = this.sum\n    this.numA = this.numB\n    this.numB = sum\n  }),\n})\n```\n\n3. 在 Component 构造器中使用：\n\n```js\nimport { storeBindingsBehavior } from 'mobx-miniprogram-bindings'\nimport { store } from './store'\n\nComponent({\n  behaviors: [storeBindingsBehavior], // 添加这个 behavior\n  data: {\n    someData: '...',\n  },\n  storeBindings: {\n    store,\n    fields: {\n      numA: () =\u003e store.numA,\n      numB: (store) =\u003e store.numB,\n      sum: 'sum',\n    },\n    actions: {\n      buttonTap: 'update',\n    },\n  },\n  methods: {\n    myMethod() {\n      this.data.sum // 来自于 MobX store 的字段\n    },\n  },\n})\n```\n\n## TypeScript 接口\n\n在 TypeScript 下，可以使用 `ComponentWithStore` 接口。它会自动处理一些类型问题。注意：\n\n* 使用这个接口时，不要在 behaviors 中额外引入 `storeBindingsBehavior` ；\n* `fields` 和 `actions` 末尾需要加上 `as const` 以便更好的类型推导；\n* `storeBindings` 如果是一个数组，也要在数组后加上 `as const` 。\n\n```js\nimport { ComponentWithStore } from 'mobx-miniprogram-bindings'\n\nComponentWithStore({\n  data: {\n    someData: '...',\n  },\n  storeBindings: {\n    store,\n    fields: ['numA', 'numB', 'sum'] as const,\n    actions: {\n      buttonTap: 'update',\n    } as const,\n  },\n})\n```\n\n`BehaviorWithStore` 接口类似。\n\n```js\nimport { BehaviorWithStore } from 'mobx-miniprogram-bindings'\n\nexport const testBehavior = BehaviorWithStore({\n  storeBindings: {\n    store,\n    fields: ['numA', 'numB', 'sum'] as const,\n    actions: ['update'] as const,\n  },\n})\n```\n\n目前 TypeScript 接口定义依赖于 `miniprogram-api-typings ^4.0.0` 。\n（如使用老版本的 api-typings ，请使用本项目的 v4 或 v3 版本。）\n\n## glass-easel Chaining API 接口\n\n使用 glass-easel Chaining API 时，使用 `initStoreBindings` 更友好。\n\n```js\nimport { initStoreBindings } from 'mobx-miniprogram-bindings'\n\nComponent()\n  .init((ctx) =\u003e {\n    const { listener } = ctx\n    initStoreBindings(ctx, {\n      store,\n      fields: ['numA', 'numB', 'sum'],\n    })\n    const buttonTap = listener(() =\u003e {\n      store.update()\n    })\n    return { buttonTap }\n  })\n  .register()\n```\n\n## 具体接口说明\n\n将页面、自定义组件和 store 绑定有两种方式： **behavior 绑定** 和 **手工绑定** 。\n\n### behavior 绑定\n\n**behavior 绑定** 适用于 `Component` 构造器。做法：使用 `storeBindingsBehavior` 这个 behavior 和 `storeBindings` 定义段。\n\n```js\nimport { storeBindingsBehavior } from 'mobx-miniprogram-bindings'\n\nComponent({\n  behaviors: [storeBindingsBehavior],\n  storeBindings: {\n    /* 绑定配置（见下文） */\n  },\n})\n```\n\n也可以把 `storeBindings` 设置为一个数组，这样可以同时绑定多个 `store` ：\n\n```js\nimport { storeBindingsBehavior } from 'mobx-miniprogram-bindings'\n\nComponent({\n  behaviors: [storeBindingsBehavior],\n  storeBindings: [\n    {\n      /* 绑定配置 1 */\n    },\n    {\n      /* 绑定配置 2 */\n    },\n  ],\n})\n```\n\n### 手工绑定\n\n**手工绑定** 更加灵活，适用于 store 需要在 `onLoad` （自定义组件 attached ）时才能确定的情况。目前，在 Page 构造器内使用时，也必须用这种方式。\n\n做法：使用 `createStoreBindings` 创建绑定，它会返回一个包含清理函数的对象用于取消绑定。\n\n注意：在页面 onUnload （自定义组件 detached ）时一定要调用清理函数，否则将导致内存泄漏！\n\n```js\nimport { createStoreBindings } from 'mobx-miniprogram-bindings'\n\nPage({\n  onLoad() {\n    this.storeBindings = createStoreBindings(this, {\n      /* 绑定配置（见下文） */\n    })\n  },\n  onUnload() {\n    this.storeBindings.destroyStoreBindings()\n  },\n})\n```\n\n### 绑定配置\n\n无论使用哪种绑定方式，都必须提供一个绑定配置对象。这个对象包含的字段如下：\n\n| 字段名  | 类型                 | 含义                         |\n| ------- | -------------------- | ---------------------------- |\n| store   | 一个 MobX observable | 默认的 MobX store            |\n| fields  | 数组或者对象         | 用于指定需要绑定的 data 字段 |\n| actions | 数组或者对象         | 用于指定需要映射的 actions   |\n\n#### `fields`\n\n`fields` 有三种形式：\n\n- 数组形式：指定 data 中哪些字段来源于 `store` 。例如 `['numA', 'numB', 'sum']` 。\n- 映射形式：指定 data 中哪些字段来源于 `store` 以及它们在 `store` 中对应的名字。例如 `{ a: 'numA', b: 'numB' }` ，此时 `this.data.a === store.numA` `this.data.b === store.numB` 。\n- 函数形式：指定 data 中每个字段的计算方法。例如 `{ a: () =\u003e store.numA, b: () =\u003e anotherStore.numB }` ，此时 `this.data.a === store.numA` `this.data.b === anotherStore.numB` 。\n\n上述三种形式中，映射形式和函数形式可以在一个配置中同时使用。\n\n如果仅使用了函数形式，那么 `store` 字段可以为空，否则 `store` 字段必填。\n\n#### `actions`\n\n`actions` 可以用于将 store 中的一些 actions 放入页面或自定义组件的 this 下，来方便触发一些 actions 。有两种形式：\n\n- 数组形式：例如 `['update']` ，此时 `this.update === store.update` 。\n- 映射形式：例如 `{ buttonTap: 'update' }` ，此时 `this.buttonTap === store.update` 。\n\n只要 `actions` 不为空，则 `store` 字段必填。\n\n## 注意事项\n\n### 延迟更新与立刻更新\n\n为了提升性能，在 store 中的字段被更新后，并不会立刻同步更新到 `this.data` 上，而是等到下个 `wx.nextTick` 调用时才更新。（这样可以显著减少 setData 的调用次数。）\n\n如果需要立刻更新，可以调用：\n\n- `this.updateStoreBindings()` （在 **behavior 绑定** 中）\n- `this.storeBindings.updateStoreBindings()` （在 **手工绑定** 中）\n\n### 与 miniprogram-computed 一起使用\n\n与 [miniprogram-computed](https://github.com/wechat-miniprogram/computed) 时，在 behaviors 列表中 `computedBehavior` 必须在后面：\n\n```js\nComponent({\n  behaviors: [storeBindingsBehavior, computedBehavior],\n  /* ... */\n})\n```\n\n### 关于部分更新\n\n如果只是更新对象中的一部分（子字段），是不会引发界面变化的！例如：\n\n```js\nComponent({\n  behaviors: [storeBindingsBehavior],\n  storeBindings: {\n    store,\n    fields: ['someObject'],\n  },\n})\n```\n\n如果尝试在 `store` 中：\n\n```js\nthis.someObject.someField = 'xxx'\n```\n\n这样是不会触发界面更新的。请考虑改成：\n\n```js\nthis.someObject = Object.assign({}, this.someObject, { someField: 'xxx' })\n```\n","funding_links":[],"categories":["mini-programe"],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwechat-miniprogram%2Fmobx-miniprogram-bindings","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwechat-miniprogram%2Fmobx-miniprogram-bindings","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwechat-miniprogram%2Fmobx-miniprogram-bindings/lists"}