一,數(shù)組和對象的深度監(jiān)聽


????1,Object.defineProperty缺點
? ? ????1)深度監(jiān)聽,需要遞歸到底,一次性計算量大
? ? ????2)無法監(jiān)聽新增屬性/刪除屬性(Vue.set,Vue.delete)
? ? ????3)無法原生監(jiān)聽數(shù)組,需要特殊處理
? ? 2,數(shù)組監(jiān)聽:就是重寫了數(shù)組的原型,更準(zhǔn)確的表達(dá)是攔截了數(shù)組的原型,然后用Object.defineProperty劫持?jǐn)?shù)組方法
????2,vue3.0,Object.defineProperty的替代方案是proxy(不能兼容ie11)、
二,響應(yīng)式的核心原理
? ? 1,Observer
? ? ? ? 將data中的數(shù)據(jù)用Object.defineProperty進(jìn)行數(shù)據(jù)劫持,每個目標(biāo)對象的鍵值(即data中的數(shù)據(jù))轉(zhuǎn)換成getter/setter形式,用于進(jìn)行依賴收集和通過依賴通知更新
? ? 2,Dep(依賴管理)
? ? ? ? 1)什么是依賴?
????????????數(shù)據(jù)響應(yīng)式后,如何通知視圖更新?Dep就是幫我們收集【究竟要通知到哪里的】
? ? ? ? 2)如何收集依賴
? ??????????我們?nèi)绾沃纃ata中的某個屬性被使用了,答案就是Object.defineProperty,因為讀取某個屬性就會觸發(fā)get方法
? ? ? ? 3)Dep就是收集與視圖相關(guān)的數(shù)據(jù),觸發(fā)了get的數(shù)據(jù),主要起到依賴收集和通知更新的作用。用于收集當(dāng)前響應(yīng)式對象的依賴關(guān)系,每個響應(yīng)式對象包括子對象都擁有一個 Dep 實例(里面 subs 是 Watcher 實例數(shù)組),當(dāng)數(shù)據(jù)有變更時,會通過 dep.notify()通知各個 watcher。
? ? ? ? 4)initState 時,對 computed 屬性初始化時,觸發(fā) computed watcher 依賴收集
? ? ? ? 5)initState 時,對偵聽屬性初始化時,觸發(fā) user watcher 依賴收集
? ? ? ? 6)render()的過程,觸發(fā) render watcher 依賴收集
? ? ? ? 7)re-render 時,vm.render()再次執(zhí)行,會移除所有 subs 中的 watcer 的訂閱,重新賦值。
? ? 3,Watcher
? ? ? ? 1)Watcher就是類似中介的角色,比如message就有三個中介,當(dāng)message變化,就通知這三個中介,他們就去執(zhí)行各自需要做的變化。
? ? ? ? 2)Watcher必須要有的2個方法。一個就是通知變化,另一個就是被收集起來到Dep中去。
? ? ? ? 3)遍歷所有的 subs(Watcher 實例),調(diào)用每一個 watcher 的 update 方法。
? ? 4,Watcher 和 Dep 的關(guān)系
????????watcher 中實例化了 dep 并向 dep.subs 中添加了訂閱者,dep 通過 notify 遍歷了 dep.subs 通知每個 watcher 更新。
三,總結(jié)
? ? 1,在數(shù)據(jù)被改的時候,觸發(fā)set方法,通過對應(yīng)的所有依賴(Watcher),去執(zhí)行更新。比如watch和computed就執(zhí)行開發(fā)者自定義的回調(diào)方法。
? ? 2,Observer中進(jìn)行響應(yīng)式的綁定,在數(shù)據(jù)被讀的時候,觸發(fā)get方法,執(zhí)行Dep來收集依賴,也就是收集Watcher。