背景
既然小程序的组件已经有Observer功能,那为什么还要手写watch功能呢?
- Observer只能在Component中使用,没法在Page中使用。若是想在Page中监控某一数据的变化,Observer做不到。
- Observer属于小程序的新功能,只能在高版本微信使用,低版本微信无法使用。公司的小程序就因为使用了Observer功能,导致很多低版本微信用户无法使用这个小程序。
实现
新建一个watch.js文件,代码如下
function watch(key, callback) {
// 先执行一次watch
callback.call(this, this.data[key])
let that = this
let tmpData = this.data[key]
Object.defineProperty(this.data, key, {
set: function(value) {
tmpData = value
// 值变化了再执行一次
callback.call(that, value)
},
get: function() {
return tmpData
}
})
}
export default watch
原理很简单,就是使用Object.defineProperty来定义要侦听的数据对象,当该值变化时,会执行其中的set方法,我们在set方法中执行侦听器回调就可以了。注:因为组件初始化的时候不会执行set方法,所以需要额外在开始的时候执行一次回调。
这个方法可以在Component的attached、ready函数中或者page的onShow、onLoad函数中使用。
Component中使用watch功能示例如下,Page中用法类似
import watch from '../../utils/watch.js'
Component({
properties: {
showPercent: {
type: Boolean,
value: true
},
percents: Array
},
attached: function() {
watch.call(this, 'percents', function (val) {
if (val && val.length >0) {
this.setData({
showPercent: true
})
} else {
this.setData({
showPercent: false
})
}
})
}
})
为了保证watch函数中的this指向,必须使用watch.call(this, ...arguments)的方式调用watch方法。这其中,第一个参数,this,固定写法;第二个参,数要watch的参数名;第三个参数,数值改变后执行的函数。
结语
实现了该watch方法,就可以解决开头说的两个问题了
- 在Page中使用侦听器
- 兼容低版本微信用户
下一篇《微信小程序实现数据侦听器watch,包含子属性的watch》有方案更高级、使用更简单、且支持子属性watch的实现方法。