在微信小程序實現 watch 屬性,監聽 data 中的屬性,當被監聽屬性的值改變時,執行咱們指定的方法。vue
Vue 的 computed 和 watch 能夠很方便的檢測數據的變化,從而作出相應的改變,因此,模仿 vue 確定是一個不錯的選擇。小程序
與 Vue 同樣,咱們使用 ES5 的Object.defineProperty()
方法,劫持對象的 getter/setter,從而實現給對象賦值時(調用 setter),執行 watch 對象中相對應的函數,達到監聽效果。微信小程序
不囉嗦,上代碼,真實可用。數組
function 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: function(value) {
watchFun.call(page, value, val);
val = value;
if (deep) {
observe(obj, key, watchFun, deep, page);
}
},
get: function() {
return val;
}
});
}
export function 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);
});
}
複製代碼
push()
,pop()
等方法並不會觸發監聽函數。import * as watch from "./watch.js";
Page({
data: {
name: "二狗子"
},
onLoad() {
watch.setWatcher(this);
},
watch: {
name: function(newVal, oldVal) {
console.log(newVal, oldVal);
}
}
});
複製代碼
onLoad
鉤子設置監聽器而後就能夠愉快的使用了。微信
watch 會使代碼更簡潔,邏輯更清晰,在響應式數據處理上很方便。函數