前言
時隔半年运翼,再寫一篇關(guān)于vue源碼的總結(jié)文章菌羽,期間剛好工作了半年(也剛好用了半年vue)渗常,也陸陸續(xù)續(xù)地看了一些別人寫的源碼分析壮不。這里再記下對vue的認(rèn)識。
vue 框架運(yùn)行的三個重要階段
- 配置項(xiàng)校驗(yàn)合并階段
參見Vue源碼分析(3)--選項(xiàng)合并過程mergeOptions - 初始化響應(yīng)式系統(tǒng)
參見Vue源碼分析(4)--實(shí)例的初始化過程 - 組件掛載皱碘、依賴收集询一、頁面更新(Virtual DOM Diff)
參見Vue源碼分析(5)--觀察者收集、組件渲染掛載過程
vue 框架的三大核心內(nèi)容
- 響應(yīng)式系統(tǒng)
data中的對象obj會被觀測(observe)癌椿,結(jié)果就是obj的每個可枚舉屬性都被配置了一個dep屬性健蕊,專門用來收集各種watcher實(shí)例(通過Object.defineProperty重寫了屬性的存取器函數(shù)辦到的)。當(dāng)組件開始掛載時(vm.$mount(vm.options.el))踢俄,組件的render函數(shù)被調(diào)用缩功,從而觸發(fā)了屬性的get函數(shù),該屬性對應(yīng)的dep就會收集當(dāng)前活躍的watcher實(shí)例(也即render watcher)都办,掛載完畢后頁面的初次渲染就完成了嫡锌。當(dāng)data中的數(shù)據(jù)發(fā)生變化時會觸發(fā)對應(yīng)屬性的set函數(shù),set函數(shù)會調(diào)用該屬性對應(yīng)的dep中的wathcer實(shí)例的run方法琳钉,該方法最終經(jīng)過Diff算法算出頁面最小變動部分势木,從而實(shí)現(xiàn)頁面更新。 - 模板編譯系統(tǒng)
通過正則手段歌懒,將vue語法格式的html字符串解析成AST啦桌,最終通過字符串拼接的方式產(chǎn)生render和renderStatic函數(shù) - 批量更新 & Diff 算法
頁面初次渲染后,如果data中的數(shù)據(jù)發(fā)生變化歼培,比如a,b兩個屬性發(fā)生變化震蒋,并不是a屬性變化時更新一下頁面,b屬性變化時再更新一下頁面躲庄,而是a,b兩個屬性都變化以后只更新一次頁面(前提是ab的變化不是異步的)查剖,這就是批量更新的意思。實(shí)現(xiàn)的原理是內(nèi)部實(shí)現(xiàn)了nextTick函數(shù)噪窘,觸發(fā)屬性的set函數(shù)時笋庄,會將該屬性收集的watcher放入隊(duì)列中,等此次事件循環(huán)結(jié)束后統(tǒng)一在下次循環(huán)時依次執(zhí)行(本質(zhì)上執(zhí)行watcher.run方法);
Diff算法是按層級比較的直砂,因此時間復(fù)雜度為o(n)菌仁,效率上是很高效的(暫未深入研究)