习惯于 VUE 或其他一些框架的同学们可能会经常使用它们的 computed
和 watch
。
小程序框架本身并没有提供这个功能,但我们基于现有的特性,做了一个 npm 模块来提供 computed
和 watch
功能。
先来个 GitHub 链接:https://github.com/wechat-miniprogram/computed
如何使用?
安装 npm 模块
npm install --save miniprogram-computed
示例代码
const computedBehavior = require('miniprogram-computed')
Component({
behaviors: [computedBehavior],
data: {
a: 1,
b: 1,
},
computed: {
sum(data) {
return data.a + data.b
},
},
})
const computedBehavior = require('miniprogram-computed')
Component({
behaviors: [computedBehavior],
data: {
a: 1,
b: 1,
sum: 2,
},
watch: {
'a, b': function(a, b) {
this.setData({
sum: a + b
})
},
},
})
怎么在页面中使用?
其实上面的示例不仅在自定义组件中可以使用,在页面中也是可以的——因为小程序的页面也可用 Component
构造器来创建!
如果你已经有一个这样的页面:
Page({
data: {
a: 1,
b: 1,
},
onLoad: function() { /* ... */ },
myMethod1: function() { /* ... */ },
myMethod2: function() { /* ... */ },
})
可以先把它改成:
Component({
data: {
a: 1,
b: 1,
},
methods: {
onLoad: function() { /* ... */ },
myMethod1: function() { /* ... */ },
myMethod2: function() { /* ... */ },
},
})
然后就可以用了:
const computedBehavior = require('miniprogram-computed')
Component({
behaviors: [computedBehavior],
data: {
a: 1,
b: 1,
},
computed: {
sum(data) {
return data.a + data.b
},
},
methods: {
onLoad: function() { /* ... */ },
myMethod1: function() { /* ... */ },
myMethod2: function() { /* ... */ },
},
})
应该使用 computed
还是 watch
?
看起来 computed
和 watch
具有类似的功能,应该使用哪个呢?
一个简单的原则: computed
只有 data
可以访问,不能访问组件的 methods
(但可以访问组件外的通用函数)。如果满足这个需要,使用 computed
,否则使用 watch
。
想知道原理?
computed
和 watch
主要基于两个自定义组件特性: 数据监听器 和 自定义组件扩展 。其中,数据监听器 observers
可以用来监听数据被 setData
操作。
- 对于
computed
,每次执行computed
函数时,记录下有哪些 data 中的字段被依赖。如果下一次setData
后这些字段被改变了,就重新执行这个computed
函数。 - 对于
watch
,它和observers
的区别不大。区别在于,如果一个 data 中的字段被设置但未被改变,普通的observers
会触发,但watch
不会。
如果遇到问题或者有好的建议,可以在 GitHub 提 issue 。
为什么就不能让page也支持observers,把page写成component很怪啊。
我现在已经回到手动时代了,即不用watch和computed,全部是手动去调用函数更新。
因为不太想过度依赖小程序框架的特性,迁移成本高且开发思维模式也不同
也曾经通过setter getter去实现。但是setData是异步这件事情导致很混乱,也不用了
推广下 开源插件 annil 解决原生框架能力不足问题
github地址:https://github.com/missannil/annil
论坛介绍:https://developers.weixin.qq.com/community/develop/article/doc/0004ee44bdc8a8bd58f134b4561813
怎么监听对象数组内的属性是否变化
现在computed只支持监听data的变化,能否进阶支持监听globalData数据的变化呀?
插件引入需要加上.behavior 不然会报错!
const computedBehavior = require('miniprogram-computed').behavior // 注意: 需要加上.behavior才好使 Component({ behaviors: [computedBehavior], data: { a: 1, b: 1, }, computed: { sum(data) { return data.a + data.b }, }, })
太难了。
对于重写了Page函数的是不是就没法用了?
const computedBehavior = require('miniprogram-computed' )
计算不了 import { storeBindingsBehavior, createStoreBindings } from'mobx-miniprogram-bindings'
mobx 里面的值
就是 你们官方 出的这两个插件 怎么配合
使用
下面的 identity 是mobx 的 可是在计算属性里面 找不到
import { storeBindingsBehavior } from'mobx-miniprogram-bindings'
const computedBehavior = require('miniprogram-computed'
const app = getApp()
Component({
behaviors: [storeBindingsBehavior, computedBehavior],
properties: {
current: {
type: String
value: 'tabBarIndex'
},
},
storeBindings: {
store: app.store,
fields: {
identity: 'identity'
},
},
computed: {
// showList: {
// require: ["$state", 'identity'],
// fn({ $state, identity }) {
// let arr = [
// ['bPostAdmin', 'tabBarTaskAdmin','tabBarMessage', 'tabBarMy'],
// ['tabBarIndex', 'tabBarDoTask', 'tabBarMessage', 'tabBarMy'],
// ][typeof identity !== 'undefined' ? identity - 1 : 1] || []
// return $state.tabBarList.filter(item => arr.includes(item.url))
// }
// },
showList (data) {
let { $state, identity } = data
let arr = [
['bPostAdmin', 'tabBarTaskAdmin', 'tabBarMessage', 'tabBarMy'],
['tabBarIndex', 'tabBarDoTask', 'tabBarMessage', 'tabBarMy'],
][typeof identity !== 'undefined' ? identity - : ] || []
return $state.tabBarList.filter(item => arr.includes(item.url))
},
},
data: {
},
methods: {
onChange(e) {
this.$_yp_goPage(e.detail)
},
}
})
报这个错不知道为啥