微信小程序(三十一)自定义watch监听属性
站长
· 阅读数 20
微信小程序并没有为我们在普通的页面中提供类似vue中watch类似的监听属性。
还是那句话,人家没给,你还想用,自己定义一个。
监听器的原理,将data中需监听的属性写在watch对象中,并给其提供一个方法,当被监听属性的值改变时,调用该方法。
所以,我们需要用到Javascript中的Object.defineProperty()方法,来手动劫持对象的getter/setter,从而实现给对象赋值时(调用setter)执行watch对象中相对应的函数,达到监听效果。
Object.defineProperty()不在这里详细介绍,详情参照《深入浅出Object.defineProperty()》
同样,VUE中的watch监听属性滥用会造成性能问题,我这里自定义的watch也是一样的,要适度使用。
一:自定义watch属性:
const observe = (obj, key, watchFun, deep, page) =>
{
let val = obj[key];
if (val != null && typeof val === "object" && deep)
{
Object.keys(val).forEach((item) => {
observe(val, item, watchFun, deep, page);
});
}
Object.defineProperty(obj, key, {
configurable: true,
enumerable: true,
set: (value) =>
{
watchFun.call(page, value, val);
val = value;
if (deep)
{
observe(obj, key, watchFun, deep, page);
}
},
get: () => {
return val;
}
});
}
/**
* @name: 自定义watch 监听属性
* @author: camellia
* @date: 2021-11-12
*/
const setWatcher = (page) =>
{
let data = page.data;
let watch = page.watch;
Object.keys(watch).forEach((item) => {
let targetData = data;
let keys = item.split(".");
for (let i = 0; i < keys.length - 1; i++)
{
targetData = targetData[keys[i]];
}
let targetKey = keys[keys.length - 1];
let watchFun = watch[item].handler || watch[item];
let deep = watch[item].deep;
observe(targetData, targetKey, watchFun, deep, page);
});
}
/**
*
// 引入自定义监听属性
const watch = require("../../utils/watch.js");
Page({
data: {
name: "时间里的"
},
onLoad() {
watch.setWatcher(this);
},
watch: {
name: function(newVal, oldVal) {
console.log(newVal, oldVal);
}
}
});
*/
module.exports = {
setWatcher
};
二:使用watch监听属性
1:文件存放位置
具体文件放在那里,这个纯看个人喜好,我在这里说一下我存放的位置仅供参考。
小程序根目录下的utils目录下:
2:调用:
(1):引入:
// 引入自定义监听属性
const watch = require("../../utils/watch.js");
(2):在onload中实例化监听函数
onLoad() {
watch.setWatcher(this);
},
(3):调用watch监听属性:
watch: {
name: function(newVal, oldVal) {
console.log(newVal, oldVal);
}
}
以下是完整的代码调用实例:
const watch = require("../../utils/watch.js");
Page({
data: {
name: "时间里的"
},
onLoad() {
watch.setWatcher(this);
},
watch: {
name: function(newVal, oldVal) {
console.log(newVal, oldVal);
}
}
});
最后再强调一下,适度的调用watch属性。否则会造成性能问题
有好的建议,请在下方输入你的评论。
欢迎访问个人博客:guanchao.site
欢迎访问我的小程序:打开微信->发现->小程序->搜索“时间里的”