监听器的原理,是将data中需监听的数据写在watch对象中,并给其提供一个方法,当被监听的数据的值改变时,调用该方法。
我们需要用到Javascript中的Object.defineProperty()方法,来手动劫持对象的getter/setter,从而实现给对象赋值时(调用setter),执行watch对象中相对应的函数,达到监听效果。
Object.defineProperty()方法,会直接在一个对象上定义一个新属性,或者修改一个对象的现有属性, 并返回这个对象。
这里假定有多个页面需要监听需求,把监听方法写在app.js中,以便全局调用
// 设置监听器
watch: function (ctx, obj) {
Object.keys(obj).forEach((key) => {
this.observer(ctx.data, key, ctx.data[key], function (value) {
obj[key].call(ctx, value);
});
});
},
// 监听属性,并执行监听函数
observer: function (data, key, val, fn) {
Object.defineProperty(data, key, {
configurable: true,
enumerable: true,
get: function () {
return val;
},
set: function (newVal) {
if (newVal === val) return;
fn && fn(newVal);
val = newVal;
},
});
},
使用时,在需要监听的页面onLoad中,调用watch方法
onLoad(options) {
// 调用监听器,监听数据变化
app.watch(this, {
searchVal: function (searchVal) {
if (searchVal) {
this.setData({
searchResult: true,
});
} else {
this.setData({
searchResult: false,
historySearchList: wx.getStorageSync("historySearch") || [],
});
}
},
});
},