vue原始碼解析 —— 資料代理
阿新 • • 發佈:2018-12-04
1. 前言:因為vue原始碼是比較複雜的,考慮的東西比較多;而這裡只是簡單的瞭解下類似vue的mvvm框架的部分原理,所以我們用這個庫: https://github.com/DMQ/mvvm (仿vue實現的mvvm庫,比vue簡介,簡單) ==>> 下面稱其為 mvvm
2. 概念解析:
1) 資料代理: 通過一個物件代理對另一個物件(在前一個物件內部)中屬性的操作(讀/寫)
2) vue 資料代理: 通過 vm 物件(即this)來代理 data 物件中所有屬性的操作
3) 好處: 更方便的操作 data 中的資料
4) 基本實現流程
a. 通過 Object.defineProperty()給 vm 新增與 data 物件的屬性對應的屬性描述符
b. 所有新增的屬性都包含 getter/setter
c. getter/setter 內部去操作 data 中對應的屬性資料
3. 基本實現 (vue實現資料代理 / mvvm實現資料代理)
3.1 vue實現資料代理
3.2 mvvm實現資料代理
4. mvvm中資料代理的原始碼(主要由Object.definePropert這個方法實現 mvvm中的mvvm.js)
/* 相關於Vue的建構函式 */ function MVVM(options) { // 將選項物件儲存到vm this.$options = options; // 將data物件儲存到vm和datq變數中 var data = this._data = this.$options.data; //將vm儲存在me變數中 var me = this; // 遍歷data中所有屬性 Object.keys(data).forEach(function (key) { // 屬性名: name // 對指定屬性實現代理 me._proxy(key); }); // 對data進行監視 observe(data, this); // 建立一個用來編譯模板的compile物件 this.$compile = new Compile(options.el || document.body, this) } MVVM.prototype = { $watch: function (key, cb, options) { new Watcher(this, key, cb); }, // 對指定屬性實現代理 ===>>> 最重要的程式碼 _proxy: function (key) { // 儲存vm var me = this; // 給vm新增指定屬性名的屬性(使用屬性描述) Object.defineProperty(me, key, { configurable: false, // 不能再重新定義 enumerable: true, // 可以列舉 // 當通過vm.name讀取屬性值時自動呼叫 get: function proxyGetter() { // 讀取data中對應屬性值返回(實現代理讀操作) return me._data[key]; }, // 當通過vm.name = 'xxx'時自動呼叫 set: function proxySetter(newVal) { // 將最新的值儲存到data中對應的屬性上(實現代理寫操作) me._data[key] = newVal; } }); } };
5. chrome瀏覽器的除錯按鈕
文章僅為本人學習過程的一個記錄,僅供參考,如有問題,歡迎指出!