前端領域的三大框架都是基於聲明式的編程,即不操縱 DOM,經過數據的變化來改變頁面,也就是實現了 model --> view 的單向數據綁定。而 vue 它是 MVVM 架構的一種實現,及雙向數據綁定,這也是 vue 中的核心內容。前端
我看的其實不是正統的 Vue 的源碼,而是 Mvvm 的一種大體實現,Vue 的核心也是基於這個庫的。 好了,要看這個基本實現庫,也是要了解一些原生 JS 的一些知識的。vue
將僞數組轉化成真數組node
Array.prototype.slice.call(ele)編程
獲得 DOM 的節點類型,通常這個屬性在庫中用的特別多,他能夠判斷出元素,文本仍是換行。數組
node.nodeTypebash
Object.defineProperty(obj, propertyName, {})架構
這個對象的方法是實現數據代理,還有數據綁定中自重要的一步,它能夠監視屬性的變化。框架
Object.keys(obj)ui
獲得對象自身可枚舉屬性組成的數組this
obj.hasOwnProperty(prop)
判斷prop是不是obj自身的屬性
DocumentFragment
文檔碎片化,咱們眼中的不直接操做DOM,DOM 的局部更新其實就是操做的這個對象。
實現數據代理的庫有不少,Vue 只是其中一個。 在 Vue 中,data 管理的數據的讀和寫操做能夠由實例 $vm 對象代理操做。這樣,咱們操做數據就方便多了,畢竟少了一個 . 的東西。
function MVVM(options) {
// 配置對象 options 傳給 this
this.$options = options;
// 取出 data 用 data 變量保存
var data = this._data = this.$options.data;
var me = this;
// 數據代理
// 實現 vm.xxx -> vm._data.xxx
// 遍歷 data 對象的全部屬性
Object.keys(data).forEach(function(key) {
me._proxy(key);
});
MVVM.prototype = {
$watch: function(key, cb, options) {
new Watcher(this, key, cb);
},
_proxy: function(key) {
var me = this;
Object.defineProperty(me, key, {
configurable: false,
enumerable: true,
get: function proxyGetter() {
return me._data[key];
},
set: function proxySetter(newVal) {
me._data[key] = newVal;
}
});
}
};
複製代碼
能夠看到,這裏的 data 變量和 options.data 的值 指向同一個對象,又由於咱們遍歷了data 裏的全部屬性,配置了 get 和 set, 所以讀值和設置新的值也會影響配置對象 options 裏的 data。