微信小程序并没有为我们在普通的页面中提供类似vue中watch类似的监听属性。
还是那句话,人家没给,你还想用,自己定义一个。
监听器的原理,将data中需监听的属性写在watch对象中,并给其提供一个方法,当被监听属性的值改变时,调用该方法。
所以,我们需要用到Javascript中的Object.defineProperty()方法,来手动劫持对象的getter/setter,从而实现给对象赋值时(调用setter)执行watch对象中相对应的函数,达到监听效果。
Object.defineProperty()不在这里详细介绍,详情参照《深入浅出Object.defineProperty()》
同样,VUE中的watch监听属性滥用会造成性能问题,我这里自定义的watch也是一样的,要适度使用。
一:自定义watch属性:
ini
复制代码
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):引入:
ini
复制代码
// 引入自定义监听属性 const watch = require("../../utils/watch.js");
(2):在onload中实例化监听函数
javascript
复制代码
onLoad() { watch.setWatcher(this); },
(3):调用watch监听属性:
css
复制代码
watch: { name: function(newVal, oldVal) { console.log(newVal, oldVal); } }
以下是完整的代码调用实例:
javascript
复制代码
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
欢迎访问我的小程序:打开微信->发现->小程序->搜索“时间里的”