摘要:與狀態(tài)同步非常困難通過(guò)添加觀察者監(jiān)測(cè)變化,如和。應(yīng)用中狀態(tài)的屬性會(huì)被監(jiān)測(cè),當(dāng)它們發(fā)生變化時(shí),只有依賴(lài)了發(fā)生變化屬性的元素會(huì)被重新渲染。
現(xiàn)代 js 框架存在的根本原因
然而通常人們(自以為)使用框架是因?yàn)椋?br>它們支持組件化;
它們有強(qiáng)大的社區(qū)支持;
它們有很多(基于框架的)第三方庫(kù)來(lái)解決問(wèn)題;
它們有很多(很好的)第三方組件;
它們有瀏覽器擴(kuò)展工具來(lái)幫助調(diào)試;
它們適合做單頁(yè)應(yīng)用。
Keeping the UI in sync with the state is hard (UI與狀態(tài)同步非常困難)
通過(guò)(添加)觀察者監(jiān)測(cè)變化,如 Angular 和 Vue.js。應(yīng)用中狀態(tài)的屬性會(huì)被監(jiān)測(cè),當(dāng)它們發(fā)生變化時(shí),只有依賴(lài)了(發(fā)生變化)屬性的 DOM 元素會(huì)被重新渲染。
1.屬性攔截器-初步數(shù)據(jù)劫持
Object.defineProperty()
let a = {} Object.defineProperty(a, "b", { enumerable: true, configurable: true, set (newValue){ console.log("set") value = newValue }, get (){ console.log("get") return value } }) value = a.b a.b = 1 console.log(a.b)
讀a.b或者設(shè)置a.b時(shí)候觸發(fā)get和set函數(shù)
configurable如果為false,那么不可以修改, 不可以刪除.
writable給的說(shuō)明是如果設(shè)置為false,不可以采用 數(shù)據(jù)運(yùn)算符,進(jìn)行賦值
2.想實(shí)現(xiàn)一個(gè)這樣的功能
當(dāng)我們?cè)噲D修改 a 的值時(shí):ins.a = 2,在控制臺(tái)將會(huì)打印 "修改了 a’,
乍一看比較簡(jiǎn)單
考慮到復(fù)雜情況,
比如如何避免收集重復(fù)的依賴(lài),如何深度觀測(cè),如何處理數(shù)組以及其他邊界條件等等
const ins = new Vue({ data: { a: 1 } }) ins.$watch("a", () => { console.log("修改了 a") })
3.收集依賴(lài), 起碼需要一個(gè)”筐“
// dep 數(shù)組就是我們所謂的“筐” const dep = [] Object.defineProperty(data, "a", { set () { // 當(dāng)屬性被設(shè)置的時(shí)候,將“筐”里的依賴(lài)都執(zhí)行一次 dep.forEach(fn => fn()) }, get () { // 當(dāng)屬性被獲取的時(shí)候,把依賴(lài)放到“筐”里 dep.push(fn) } }) $watch("a", () => { console.log("設(shè)置了 a") })
4.$watch 函數(shù)是知道當(dāng)前正在觀測(cè)的是哪一個(gè)字段的
const data = { a: 1 } const dep = [] Object.defineProperty(data, "a", { set () { dep.forEach(fn => fn()) }, get () { // 此時(shí) Target 變量中保存的就是依賴(lài)函數(shù) dep.push(Target) } }) // Target 是全局變量 let Target = null function $watch (exp, fn) { // 將 Target 的值設(shè)置為 fn Target = fn // 讀取字段值,觸發(fā) get 函數(shù) data[exp] }
明白數(shù)據(jù)響應(yīng)系統(tǒng)的整體思路,為接下來(lái)真正進(jìn)入 Vue 源碼做必要的鋪墊
4.observer
observe工廠函數(shù)
const data = { a: 1 } const data = { a: 1, // __ob__ 是不可枚舉的屬性 __ob__: { value: data, // value 屬性指向 data 數(shù)據(jù)對(duì)象本身,這是一個(gè)循環(huán)引用 dep: dep實(shí)例對(duì)象, // new Dep() vmCount: 0 } }
new Observer(data)
Observer構(gòu)造函數(shù)-調(diào)用this.walk(value)-defineReactive(get和set)
get 調(diào)用 dep.depend() 在 get 函數(shù)中如何收集依賴(lài)
set 調(diào)用 dep.notify() 通知更新
5.dep
static target; // watcher id; //記錄id不能重復(fù)收集 subs; //數(shù)組,sub收集所以的watcher
dep.notify()實(shí)際上是 watcher里的update() 渲染更新
dep.depend()實(shí)際上是 watcher里的update() 渲染更新 把watcher實(shí)例對(duì)象推入subs
6.watcher
vm, vue實(shí)例對(duì)象
expOrFn, 表達(dá)式
cb, 回調(diào)函數(shù)
當(dāng)然還在vm上定義了很多其他的computer,watch之類(lèi)的
收集依賴(lài),要想收集,必須 new watcher()
get () { pushTarget(this) } addDep (){ dep.addSub(this) // 把watcher自己加入dep.subs數(shù)組 } update(){ queueWatcher() //排隊(duì)渲染 }
6.總結(jié)
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/97375.html
摘要:執(zhí)行的時(shí)候,會(huì)綁定上下文對(duì)象為組件實(shí)例于是中的就能取到組件實(shí)例本身,的代碼塊頂層作用域就綁定為了組件實(shí)例于是內(nèi)部變量的訪問(wèn),就會(huì)首先訪問(wèn)到組件實(shí)例上。其中的獲取,就會(huì)先從組件實(shí)例上獲取,相當(dāng)于。 寫(xiě)文章不容易,點(diǎn)個(gè)贊唄兄弟專(zhuān)注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺(jué)得...
摘要:接下來(lái)要看看這個(gè)訂閱者的具體實(shí)現(xiàn)了實(shí)現(xiàn)訂閱者作為和之間通信的橋梁,主要做的事情是在自身實(shí)例化時(shí)往屬性訂閱器里面添加自己自身必須有一個(gè)方法待屬性變動(dòng)通知時(shí),能調(diào)用自身的方法,并觸發(fā)中綁定的回調(diào),則功成身退。 本文能幫你做什么?1、了解vue的雙向數(shù)據(jù)綁定原理以及核心代碼模塊2、緩解好奇心的同時(shí)了解如何實(shí)現(xiàn)雙向綁定為了便于說(shuō)明原理與實(shí)現(xiàn),本文相關(guān)代碼主要摘自vue源碼, 并進(jìn)行了簡(jiǎn)化改造,...
摘要:儲(chǔ)存訂閱器因?yàn)閷傩员槐O(jiān)聽(tīng),這一步會(huì)執(zhí)行監(jiān)聽(tīng)器里的方法這一步我們把也給弄了出來(lái),到這一步我們已經(jīng)實(shí)現(xiàn)了一個(gè)簡(jiǎn)單的雙向綁定了,我們可以嘗試把兩者結(jié)合起來(lái)看下效果??偨Y(jié)本文主要是對(duì)雙向綁定原理的學(xué)習(xí)與實(shí)現(xiàn)。 當(dāng)今前端天下以 Angular、React、vue 三足鼎立的局面,你不選擇一個(gè)陣營(yíng)基本上無(wú)法立足于前端,甚至是兩個(gè)或者三個(gè)陣營(yíng)都要選擇,大勢(shì)所趨。 所以我們要時(shí)刻保持好奇心,擁抱變化,...
摘要:所以無(wú)需太過(guò)介懷是實(shí)現(xiàn)的單向或雙向綁定。監(jiān)聽(tīng)數(shù)據(jù)綁定更新函數(shù)的處理是在這個(gè)方法中,通過(guò)添加回調(diào)來(lái)接收數(shù)據(jù)變化的通知至此,一個(gè)簡(jiǎn)單的就完成了,完整代碼。 本文能幫你做什么?1、了解vue的雙向數(shù)據(jù)綁定原理以及核心代碼模塊2、緩解好奇心的同時(shí)了解如何實(shí)現(xiàn)雙向綁定為了便于說(shuō)明原理與實(shí)現(xiàn),本文相關(guān)代碼主要摘自vue源碼, 并進(jìn)行了簡(jiǎn)化改造,相對(duì)較簡(jiǎn)陋,并未考慮到數(shù)組的處理、數(shù)據(jù)的循環(huán)依賴(lài)等,也...
閱讀 3486·2021-10-13 09:39
閱讀 1468·2021-10-08 10:05
閱讀 2273·2021-09-26 09:56
閱讀 2289·2021-09-03 10:28
閱讀 2688·2019-08-29 18:37
閱讀 2047·2019-08-29 17:07
閱讀 609·2019-08-29 16:23
閱讀 2200·2019-08-29 11:24