此篇主要手寫 vue2.0 原始碼-渲染更新原理
採用觀察者模式 定義 watcher 和 dep 完成依賴收集和派發更新 從而實現渲染更新.
適用人群:沒時間去看官方原始碼或者看原始碼看的比較懵而不想去看的同學
1.定義 watcher// src/observer/watcher.js
// 全域性變數id 每次new watcher都會自增
let id = 0;
export default class watcher
// 例項化就會預設呼叫get方法
this.get();
} get()
}
在 observer 資料夾下新建 watcher.js 代表和觀察者相關 這裡首先介紹 vue 裡面使用到的觀察者模式 我們可以把 watcher 當做觀察者 它需要訂閱資料的變動 當資料變動之後 通知它去執行某些方法 其實本質就是乙個建構函式 初始化的時候會去執行 get 方法
2.建立渲染 watcher
// src/lifecycle.js
export function mountcomponent(vm, el) ;
new watcher(vm, updatecomponent, null, true);
}
我們在元件掛載方法裡面 定義乙個渲染 watcher 主要功能就是執行核心渲染頁面的方法
3.定義 dep
// src/observer/dep.js
// dep和watcher是多對多的關係
// 每個屬性都有自己的dep
let id = 0; //dep例項的唯一標識
export default class dep
}// 預設dep.target為null
dep.target = null;
dep 也是乙個建構函式 可以把他理解為觀察者模式裡面的被觀察者 在 subs 裡面收集 watcher 當資料變動的時候通知自身 subs 所有的 watcher 更新
dep.target 是乙個全域性 watcher 指向 初始狀態是 null
4.物件的依賴收集
// src/observer/index.js
// object.defineproperty資料劫持核心 相容性在ie9以及以上
function definereactive(data, key, value)
return value;
},set(newvalue) ,
});}
上訴**就是依賴收集和派發更新的核心 其實就是在資料被訪問的時候 把我們定義好的渲染 watcher 放到 dep 的 subs 陣列裡面 同時把 dep 例項物件也放到渲染 watcher 裡面去 資料更新時就可以通知 dep 的 subs 儲存的 watcher 更新
5.完善 watcher
// src/observer/watcher.js
import from "./dep";
// 全域性變數id 每次new watcher都會自增
let id = 0;
export default class watcher
// 例項化就會預設呼叫get方法
this.get();
} get()
// 把dep放到deps裡面 同時保證同乙個dep只被儲存到watcher一次 同樣的 同乙個watcher也只會儲存在dep一次
adddep(dep)
} // 這裡簡單的就執行以下get方法 之後涉及到計算屬性就不一樣了
update()
}
watcher 在呼叫 getter 方法前後分別把自身賦值給 dep.target 方便進行依賴收集 update 方法用來更新
6.完善 dep
// src/observer/dep.js
// dep和watcher是多對多的關係
// 每個屬性都有自己的dep
let id = 0; //dep例項的唯一標識
export default class dep
depend()
} notify()
addsub(watcher)
}// 預設dep.target為null
dep.target = null;
// 棧結構用來存watcher
const targetstack = ;
export function pushtarget(watcher)
export function poptarget()
定義相關的方法把收集依賴的同時把自身也放到 watcher 的 deps 容器裡面去
思考? 這時物件的更新已經可以滿足了 但是如果是陣列 類似 a.push(4) 並不會觸發自動更新 因為我們陣列並沒有收集依賴7.陣列的依賴收集
// src/observer/index.js
// object.defineproperty資料劫持核心 相容性在ie9以及以上
function definereactive(data, key, value) 屬性a對應的值是乙個陣列 觀測陣列的返回值就是對應陣列的observer例項物件
childob.dep.depend();
if (array.isarray(value)) 這種陣列多層巢狀 陣列包含陣列的情況 那麼我們訪問a的時候 只是對第一層的陣列進行了依賴收集 裡面的陣列因為沒訪問到 所以五大收集依賴 但是如果我們改變了a裡面的第二層陣列的值 是需要更新頁面的 所以需要對陣列遞迴進行依賴收集
if (array.isarray(value)) }}
}return value;
},set(newvalue) ,
});}// 遞迴收集陣列依賴
function dependarray(value)
}}
如果物件屬性的值是乙個陣列 那麼執行 childob.dep.depend()收集陣列的依賴 如果陣列裡面還包含陣列 需要遞迴遍歷收集 因為只有訪問資料觸發了 get 才會去收集依賴 一開始只是遞迴對資料進行響應式處理無法收集依賴 這兩點需要分清
8.陣列的派發更新
// src/observer/array.js
methodstopatch.foreach((method) => 那麼我們使用a.push(4) this就是a ob就是a.__ob__ 這個屬性代表的是該資料已經被響應式觀察過了 __ob__物件指的就是observer例項
const ob = this.__ob__;
let inserted;
switch (method)
if (inserted) ob.observearray(inserted); // 對新增的每一項進行觀測
ob.dep.notify(); //陣列派發更新 ob指的就是陣列對應的observer例項 我們在get的時候判斷如果屬性的值還是物件那麼就在observer例項的dep收集依賴 所以這裡是一一對應的 可以直接更新
return result;
};});
關鍵**就是 ob.dep.notify()
9.渲染更新的思維導圖
這裡放一張 整個 vue 響應式原理的 咱們從資料劫持–>模板解析–>模板渲染–>資料變化檢視自動更新整個流程已經手寫了一遍 尤其是此篇介紹的渲染更新相關的知識點 建議反覆理解原理之後自己動手實現一遍 因為vue 很多核心原理和 api 都跟這裡的知識點相關哈
最後如果覺得本文有幫助 記得點贊三連哦 十分感謝!
手寫Vue2 0原始碼 渲染更新原理
此篇主要手寫 vue2.0 原始碼 渲染更新原理 採用觀察者模式 定義 watcher 和 dep 完成依賴收集和派發更新 從而實現渲染更新.適用人群 沒時間去看官方原始碼或者看原始碼看的比較懵而不想去看的同學 1.定義 watcher src observer watcher.js 全域性變數id...
手寫Vue2 0原始碼 渲染更新原理
前言 此篇主要手寫 vue2.0 原始碼 渲染更新原理 採用觀察者模式 定義 watcher 和 dep 完成依賴收集和派發更新 從而實現渲染更新.適用人群 沒時間去看官方原始碼或者看原始碼看的比較懵而不想去看的同學 正文 我們在這裡模擬更新 settimeout 1000 1.定義 watcher...
vue2 0原始碼學習一(vue原始碼構建過程)
前提知識背景 vue.js的打包構建是基於rollup進行的 1.開啟專案的package.json,在裡面可以看到很多配置項以及命令,今天先學習 的構建,需要關注下圖地方 這裡使用的build命令就是平時在使用vue cli打包的時候觸發的命令,可以看到它其實是執行了乙個node程式,執行scri...