miniprogram-computed adds computed and watch to WeChat mini program components
小程序自定义组件 computed / watch 扩展
At a glance
- What is it?
- miniprogram-computed is a WeChat mini program behavior that recomputes computed fields and fires watch listeners when data or properties change, with a TypeScript helper constructor and support for the glass-easel Chaining API. It suits mini program developers who miss reactive patterns, and it needs the developer tools npm build to work at all.
- Who is it for?
- Adopt miniprogram-computed when you are building WeChat mini program components and want derived values and change listeners without hand wiring setData calls, and use the built-in observers when a single field change is all you need. Verify first that your project uses the developer tools npm build, because the behavior depends on it, and check whether your mini program base library version is at least 2.11.0 before assuming the package will run.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 60 days ago.
- What is it written in?
- Mainly TypeScript, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The gap this package fills is reactivity, not rendering
The WeChat mini program does not give you Vue style reactive properties. Components carry a data object and a properties option, and when you want a derived value you write a setData call by hand. The package description is that it is a mini program custom component extension behavior providing implementations of computed properties and watch listeners, and that when data or properties change it recomputes the computed fields and triggers the watch listeners. That is the whole problem statement, and it is narrower than it might sound. This is not a renderer, not a state manager and not a router. It is a behavior that other components include, after which they gain a computed section and a watch section that work the way a front end developer expects. If your pain is that every derived value requires a manual setData in the right place, this is aimed squarely at that.
The behavior is a normal WeChat behavior you add to the list
The integration point is the standard behaviors array of a component, so adoption does not require restructuring the component. The published example imports the behavior and lists it alongside your own behaviors:
const computedBehavior = require('miniprogram-computed').behavior
Component({
behaviors: [computedBehavior],Because it is a behavior and not a base class, your own behaviors keep working, and the computed functions can read data contributed by another behavior in the same list. That is a small but important detail, because in a mini program a behavior is how you share data and methods between components, and a derived value that only sees its own component's data would be less useful than it looks. The package is distributed on npm as miniprogram-computed, and the documentation states that the behavior depends on the developer tools npm build, with a link to the official npm documentation for the details. That dependency is the single most important practical constraint in the project, and it is stated up front.
Installing it needs a base library of 2.11.0 or newer
The quick experience section states that an environment with a mini program base library version of 2.11.0 or newer is required, and the package is installed with npm:
npm install --save miniprogram-computedAfter that you need to install and build the corresponding npm package before the code snippet can be tried, which the documentation calls out explicitly, and the project also points at a hosted code snippet that demonstrates the basic usage. The distinction between installing and building is not pedantic here. The WeChat developer tools have their own npm build step that turns the node_modules tree into something the mini program runtime can consume, and a package that is present in package.json but not built will simply not be found at runtime. The documentation links to the official npm page for the developer tools, so the build step is documented by the platform rather than by this project. Everything in the repository suggests this is a deliberate choice rather than an accident, since the package has a real test suite and a build pipeline of its own.
A watch listener fires only when the value actually changed
The watch section is where the package differs most usefully from what the mini program offers by default, and the comparison the documentation draws is worth repeating. A watch handler is declared with a field path and a function, and the function receives the new values followed by the old ones:
const computedBehavior = require('miniprogram-computed').behavior
Component({
behaviors: [computedBehavior],
data: {
a: 1,
b: 1,
sum: 2,
},
watch: {
'a, b': function (a, b, oldA, oldB) {
this.setData({
sum: a + b,
})
},
},The documentation states that the built in observers are triggered whether or not the field really changed, whereas watch triggers only when the field value changed, and that it passes parameters when it fires. That difference is the reason to adopt this package rather than to use observers. A handler that runs on every setData is a handler that runs your setData, and if the handler sets data, you have built a loop. A handler that only fires on a real change breaks that cycle naturally. The old value arguments are what let a handler distinguish a change from a repeated write of the same value.
Change detection is shallow unless you use the wildcard
The comparison rules are spelled out and they are not symmetric. For fields that do not use the wildcard, the check of whether the value changed is a rough shallow comparison using ===. For fields that use the wildcard, a deep comparison is performed to try to detect precisely whether the object really changed, and that requires the object fields to contain no cycles, similar to JSON.stringify. The wildcard itself is available on the watch field and can listen to changes in the child fields of a field, similar to the built in observers:
const computedBehavior = require('miniprogram-computed').behavior
Component({
behaviors: [computedBehavior],
data: {
obj: {
a: 1,
b: 2,
},
},
watch: {
'obj.**': function (obj) {
this.setData({
sum: obj.a + obj.b,
})
},The deep comparison has a cost, and the no cycles requirement is a real constraint, since a self referencing object in the data will break the detection rather than the comparison result. It is a fair trade for nested structures, but a plain field comparison is cheaper and sufficient more often than not.
computed cannot reach this, so the choice between them is not a style preference
The documentation answers the computed or watch question directly, and the answer has a technical reason behind it. Fundamentally, watch has better performance than computed, but computed is simpler and cleaner to use. The reason is that a computed field can only depend on the data object and on other computed fields, and it cannot access this. The example code comments the same restriction twice, in both the plain JavaScript example and the TypeScript one, noting that a computed function cannot access this and that only the data object is available, and that the return value is set into the this.data.sum field. So if a derivation genuinely needs the component instance, for example a method call or a piece of instance state, watch is not an alternative you choose for style reasons, it is the only option the package offers. The performance note is also worth understanding rather than accepting on faith, since a computed value is recalculated on every data change while a watch handler runs only when the watched fields change.
TypeScript users get a constructor instead of a behavior
The TypeScript story is handled in two ways, and the reason is a limitation of the type definitions rather than a preference. Because the behavior based approach cannot get type support, the package provides a helper component constructor. The ComponentWithComputed constructor gives the compiler automatic completion and type support for the computed and watch fields, and the documentation states that when you use this constructor you do not need to add the computedBehavior manually, because the constructor adds the behavior itself. There is also a BehaviorWithComputed constructor for the Behavior case. The problem it solves is specific: if you develop a mini program in TypeScript and use the Component constructor, defining a computed or watch field produces a type error, and the recommended fix is to use ComponentWithComputed instead. The glass-easel Chaining API path is a third option, where computed and watch are imported as functions and called inside an init callback, which gives typed parameters for the watcher.
Watch control helpers let you suspend and flush listeners
Three helper methods on this let you control when watch listeners run, which matters when you are doing bulk updates or when an intermediate state should not trigger a cascade. disableWatches temporarily disables watch. enableWatches re-enables watch, and if the triggerNow argument is true it immediately triggers all watch listeners. triggerAllWatches immediately triggers all watch listeners once. With the Chaining API, the return value of the watch call carries these methods, so the same controls are available in that style. This is a small feature set and it is the right one, because a reactive system without a way to suspend listeners will eventually push you into a guard variable of your own, and every project ends up writing that guard slightly differently. The package is MIT licensed, so there is no obstacle to vendoring it into a proprietary mini program, and the repository is not archived with the last push on 2026-08-24.
Editorial conclusion
Adopt miniprogram-computed when you are building WeChat mini program components and want derived values and change listeners without hand wiring setData calls, and use the built-in observers when a single field change is all you need. Verify first that your project uses the developer tools npm build, because the behavior depends on it, and check whether your mini program base library version is at least 2.11.0 before assuming the package will run.
Frequently asked questions
How do I install miniprogram-computed?
Run npm install --save miniprogram-computed, then build the npm package with the WeChat developer tools npm build, which the behavior depends on. A mini program base library version of 2.11.0 or newer is required.
How is computed used in a mini program component?
Add the behavior from miniprogram-computed to the behaviors array and declare a computed object. Each function receives the data object, cannot access this, and its return value is written to the matching this.data field.
What is the difference between watch and the built-in observers?
The built-in observers are triggered whether or not the field really changed, while watch triggers only when the field value changed and passes parameters when it fires.
How do I get TypeScript support for computed and watch?
Use the ComponentWithComputed constructor instead of the Component constructor, and a BehaviorWithComputed constructor for behaviors. When using the constructor you do not need to add the computedBehavior manually, since the constructor adds it.
Is miniprogram-computed still maintained?
The repository is not archived and the last push was on 2026-08-24. The licence is MIT, and the package name on npm is miniprogram-computed, with a peer dependency on miniprogram-api-typings.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/wechat-miniprogram-computed)Was this useful?