微信小程序,實現 watch 屬性,監聽數據變化

目標

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

思路

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 會使代碼更簡潔,邏輯更清晰,在響應式數據處理上很方便。函數

相關文章
相關標籤/搜索