1. 程式人生 > >微信小程式,實現 watch 屬性,監聽資料變化

微信小程式,實現 watch 屬性,監聽資料變化

目標

在微信小程式實現 watch 屬性,監聽data中的屬性,當被監聽屬性的值改變時,執行我們指定的方法。​​

思路

Vue 的computedwatch可以很方便的檢測資料的變化,從而做出相應的改變,所以,模仿 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); }); } 複製程式碼

注意事項:

  • watch 只能監聽已存在的屬性,陣列的 push()pop()等方法並不會觸發監聽函式。

使用

import * as watch from "./watch.js";

Page({
  data: {
    name: "二狗子"
  },

  onLoad() {
    watch.setWatcher(this);
  },

  watch: {
    name: function(newVal, oldVal) {
      console.log(newVal, oldVal);
    }
  }
});
複製程式碼
  • 首先在需要的頁面引入
  • 在 Page 的onLoad鉤子設定監聽器

然後就可以愉快的使用了。

總結

watch 會使程式碼更簡潔,邏輯更清晰,在響應式資料處理上很方便。