{"id":18938232,"url":"https://github.com/wechat-miniprogram/computed","last_synced_at":"2025-04-08T09:10:13.051Z","repository":{"id":39423575,"uuid":"145373872","full_name":"wechat-miniprogram/computed","owner":"wechat-miniprogram","description":"小程序自定义组件 computed / watch 扩展","archived":false,"fork":false,"pushed_at":"2024-05-28T09:51:42.000Z","size":1458,"stargazers_count":632,"open_issues_count":9,"forks_count":60,"subscribers_count":11,"default_branch":"master","last_synced_at":"2024-05-29T01:17:15.134Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","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":"2018-08-20T06:12:14.000Z","updated_at":"2024-05-30T06:53:58.253Z","dependencies_parsed_at":"2023-02-08T08:30:34.280Z","dependency_job_id":"f5ae178b-899b-47ae-a6ac-a1da21ab43d7","html_url":"https://github.com/wechat-miniprogram/computed","commit_stats":{"total_commits":137,"total_committers":14,"mean_commits":9.785714285714286,"dds":0.5036496350364963,"last_synced_commit":"f5a8faa3c13e60c4d529797d19a0468b7127231c"},"previous_names":[],"tags_count":29,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wechat-miniprogram%2Fcomputed","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wechat-miniprogram%2Fcomputed/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wechat-miniprogram%2Fcomputed/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wechat-miniprogram%2Fcomputed/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wechat-miniprogram","download_url":"https://codeload.github.com/wechat-miniprogram/computed/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247809964,"owners_count":20999816,"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-11-08T12:13:50.335Z","updated_at":"2025-04-08T09:10:13.009Z","avatar_url":"https://github.com/wechat-miniprogram.png","language":"TypeScript","readme":"# computed\n\n小程序自定义组件扩展 behavior，计算属性 `computed` 和监听器 `watch` 的实现。在 data 或者 properties 改变时，会重新计算 `computed` 字段并触发 `watch` 监听器。\n\n\u003e 此 behavior 依赖开发者工具的 npm 构建。具体详情可查阅[官方 npm 文档](https://developers.weixin.qq.com/miniprogram/dev/devtools/npm.html)。\n\n注意： 4.0.0 大版本变更了最基本的接口名，从低版本升级到 4.0.0 以上时请注意 [#60](https://github.com/wechat-miniprogram/computed/issues/60) 的问题。\n\n\n## 使用方法\n\n### 快速体验\n\n需要小程序基础库版本 \u003e= 2.11.0 的环境。\n\n可以直接体验一下这个代码片段，它包含了基本用法示例：[https://developers.weixin.qq.com/s/4KYn6TmJ7osP](https://developers.weixin.qq.com/s/4KYn6TmJ7osP)\n\n体验该代码片段前，需要先安装并构建相对应的 npm 包。\n\n```shell\nnpm install --save miniprogram-computed\n```\n\n### computed 基本用法\n\n```js\n// component.js\nconst computedBehavior = require('miniprogram-computed').behavior\nconst behaviorTest = require('./behavior-test') // 引入自定义 behavior\n\nComponent({\n  behaviors: [behaviorTest, computedBehavior],\n  data: {\n    a: 1,\n    b: 1,\n  },\n  computed: {\n    sum(data) {\n      // 注意： computed 函数中不能访问 this ，只有 data 对象可供访问\n      // 这个函数的返回值会被设置到 this.data.sum 字段中\n      return data.a + data.b + data.c // data.c 为自定义 behavior 数据段\n    },\n  },\n  methods: {\n    onTap() {\n      this.setData({\n        a: this.data.b,\n        b: this.data.a + this.data.b,\n      })\n    },\n  },\n})\n```\n\n```js\n//behavior-test.js\nmodule.exports = Behavior({\n  data: {\n    c: 2,\n  },\n})\n```\n\n```xml\n\u003cview\u003eA = {{a}}\u003c/view\u003e\n\u003cview\u003eB = {{b}}\u003c/view\u003e\n\u003cview\u003eSUM = {{sum}}\u003c/view\u003e\n\u003cbutton bindtap=\"onTap\"\u003eclick\u003c/button\u003e\n```\n\n### watch 基本用法\n\n```js\nconst computedBehavior = require('miniprogram-computed').behavior\n\nComponent({\n  behaviors: [computedBehavior],\n  data: {\n    a: 1,\n    b: 1,\n    sum: 2,\n  },\n  watch: {\n    'a, b': function (a, b) {\n      this.setData({\n        sum: a + b,\n      })\n    },\n  },\n  methods: {\n    onTap() {\n      this.setData({\n        a: this.data.b,\n        b: this.data.a + this.data.b,\n      })\n    },\n  },\n})\n```\n\n```xml\n\u003cview\u003eA = {{a}}\u003c/view\u003e\n\u003cview\u003eB = {{b}}\u003c/view\u003e\n\u003cview\u003eSUM = {{sum}}\u003c/view\u003e\n\u003cbutton bindtap=\"onTap\"\u003eclick\u003c/button\u003e\n```\n\n### glass-easel Chaining API 支持\n\n使用 glass-easel Chaining API 时，可以用更友好的 `computed` `watch` 函数。\n\n```js\nimport { computed, watch } from 'miniprogram-computed'\n\nComponent()\n  .data(() =\u003e ({\n    a: 1,\n    b: 2,\n  }))\n  .init((ctx) =\u003e {\n    const data = computed(ctx, {\n      c: (data) =\u003e data.a + data.b,\n      d: (data) =\u003e data.a * 2,\n    }, {\n      e: (data) =\u003e data.c + data.d,\n    })\n    watch(ctx, 'a, b', (a: number, b: number) =\u003e {\n      // ...\n    })\n  })\n  .register()\n```\n\n### 非 chaining API 的 TypeScript 支持\n\n由于通过 behavior 的方式引入不能获得类型支持, 因此为了获得类型的支持, 可以使用一个辅助组件构造器：\n\n```ts\nimport { ComponentWithComputed } from 'miniprogram-computed'\n\nComponentWithComputed({\n  data: {\n    a: 1,\n    b: 1,\n    sum: 2,\n  },\n  watch: {\n    'a, b': function (a, b) {\n      this.setData({\n        sum: a + b,\n      })\n    },\n  },\n  computed: {\n    sum(data) {\n      // 注意： computed 函数中不能访问 this ，只有 data 对象可供访问\n      // 这个函数的返回值会被设置到 this.data.sum 字段中\n      return data.a + data.b + data.sum // data.c 为自定义 behavior 数据段\n    },\n  },\n})\n```\n\n当使用该构造器的时候, 编译器可以给 `computed` 和 `watch` 提供自动提示和类型支持。\n\n**注意: 当使用该构造器的时候, 无需手动加入 `computedBehavior` , 该构造器会自动引入该 behavior 。**\n\n（类似地，也有 `BehaviorWithComputed` 构造器对应于 `Bahavior` 。）\n\n**关于 TS 兼容问题**\n\n若在小程序中用 `TypeScript` 进行开发并使用到了 `Component` 构造器。这时定义 `computed` 或 `watch` 字段会出现类型报错。\n\n针对此问题，推荐使用 `ComponentWithComputed` 构造器代替 `Component` 构造器。\n\n### 其他 API\n\n有一些辅助 API 用于控制 `watch` 时的一些行为表现。可以在 `this` 上访问到这些方法；使用 Chaining API 时， `watch()` 的返回值会带有这些方法。\n\n| 方法名 | 参数示例 | 说明 |\n| ---- | ---- | ---- |\n| disableWatches | disableWatches() | 暂时禁用 watch |\n| enableWatches | enableWatches(triggerNow) | 启用 watch ，如果 `triggerNow` 为真，立刻触发所有 watch |\n| triggerAllWatches | triggerAllWatches() | 立刻触发所有 watch 一次 |\n\n\n## 常见问题说明\n\n### 我应该使用 computed 还是 watch ？\n\n从原理上说， `watch` 的性能比 `computed` 更好；但 `computed` 的用法更简洁干净。\n\n此外， `computed` 字段状态只能依赖于 `data` 和其他 `computed` 字段，不能访问 `this` 。如果不可避免要访问 `this` ，则必须使用 `watch` 代替。\n\n### watch 和小程序基础库本身的 observers 有什么区别？\n\n- 无论字段是否真的改变， `observers` 都会被触发，而 `watch` 只在字段值改变了的时候触发，并且触发时带有参数。\n\n### 关于 \\*\\* 通配符\n\n在 `watch` 字段上可以使用 `**` 通配符，它能够监听这个字段下的子字段的变化（类似于小程序基础库本身的 observers ）。\n\n```js\nconst computedBehavior = require('miniprogram-computed').behavior\n\nComponent({\n  behaviors: [computedBehavior],\n  data: {\n    obj: {\n      a: 1,\n      b: 2,\n    },\n  },\n  watch: {\n    'obj.**': function (obj) {\n      this.setData({\n        sum: obj.a + obj.b,\n      })\n    },\n  },\n  methods: {\n    onTap() {\n      this.setData({\n        'obj.a': 10,\n      })\n    },\n  },\n})\n```\n\n除此以外：\n\n- 对于没有使用 `**` 通配符的字段，在 `watch` 检查值是否发生变化时，只会进行粗略的浅比较（使用 `===` ）；\n- 对于使用了 `**` 通配符的字段，则会进行深比较，来尝试精确检测对象是否真的发生了变化，这要求对象字段不能包含循环（类似于 `JSON.stringify` ）。\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwechat-miniprogram%2Fcomputed","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwechat-miniprogram%2Fcomputed","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwechat-miniprogram%2Fcomputed/lists"}