一個利用defineProperty實現的MVVM雙向數據綁html
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Vue-MVVM</title> </head> <body> <input type="text" id="input1" value="" oninput="myFun()" /> <input type="text" id="input2" /> </body> <script> function myFun() { o._data.test = document.getElementById('input1').value } /* 這個函數用來模擬視圖更新 */ function cb(val) { console.log('試圖更新啦~~'); document.getElementById('input2').value = val } /* 遍歷全部屬性的方式對該對象的每個屬性都經過 defineReactive */ function observer(value) { if (!value || (typeof value !== 'object')) { return; } Object.keys(value).forEach((key) => { defineReactive(value, key, value[key]); }) } /* 實現對對象的「響應式」 */ function defineReactive(obj, key, val) { Object.defineProperty(obj, key, { enumerable: true, // 可否被遍歷,好比 for in,默認值爲 false configurable: true, // 描述該屬性的描述符可否被改變,默認值爲 false get: function reactiveGetter() { // 取值的時候調用,默認值爲 false return val; }, set: function reactiveSetter(newVal) { // 設置值的時候使用 if (newVal === val) return; cb(newVal); } }); } /* 聲明類 */ class Vue { constructor(options) { this._data = options.data; observer(this._data) } } /* 建立實例 */ var o = new Vue({ data: { test: "" } }) </script> </html>