摘要:寫文章不容易,點個贊唄兄弟專注源碼分享,文章分為白話版和源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于版本如果你覺得排版難看,請點擊下面鏈接或者拉到下面關(guān)注公眾號也可以吧原理白話版終于到了要講白話的時候了
寫文章不容易,點個贊唄兄弟
專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧
研究基于 Vue版本 【2.5.17】
如果你覺得排版難看,請點擊 下面鏈接 或者 拉到 下面關(guān)注公眾號也可以吧
【Vue原理】Compile - 白話版
終于到了要講 compile 白話的時候了,大家準(zhǔn)備好了嗎,白話版肯定不會很復(fù)雜啦,源碼版就不一定了。。。
源碼版我寫了9篇??!每篇的篇幅都很長?。?!我都快寫奔潰了啊??!
都快堅持不下來了,我算了算, compile 的源碼版,我好像快寫了一個多月???
臥槽,竟然寫了這么久.....
好吧,現(xiàn)在開始我們的正文
Compilecompile 的內(nèi)容非常多,大致分為三塊主要內(nèi)容,我也稱他們是Vue的 渲染三巨頭
就是 parse,optimize,generate
雖然分為三塊,但是要明確一點
compile 的作用是解析模板,生成渲染模板的 render
比如這樣的模板經(jīng)過 compile 之后,就會生成下面的 render
_c("div", [_c("span"), _v(num)])
而 render 的作用,也是為了生成跟模板節(jié)點一一對應(yīng)的 Vnode
{ tag: "div", children:[{ tag: "span", text: undefined },{ tag: undefined text: "111" }] }
下面我們就來一個個看渲染三巨頭
Parse這是 compile 的第一個步驟
作用是接收 template 原始模板,按照模板的節(jié)點 和數(shù)據(jù) 生成對應(yīng)的 ast
比如這樣生成的 ast 是這樣,所有模板中出現(xiàn)的數(shù)據(jù),你都可以在 ast 中找到
{ tag: "div", attrsMap: {test: "2"}, children:[{ tag: "span", children: [], attrsMap: {name: "1"} }] }
ast 是什么?個人簡單理解的話
以數(shù)據(jù)的形式去描述一個東西的所有的特征吧,說錯別打我
比如說ast 描述我
{ name: "神仙朱", sex: 1, desc: "一個靚仔" }
具體可以查一下,相關(guān)內(nèi)容挺多的
另外,這里不會講細(xì)節(jié),parse 是怎么生成 ast 的,因為涉及很多源碼,放在源碼版了
Optimize這是 compile 的第二步
作用是遍歷遞歸每一個ast節(jié)點,標(biāo)記靜態(tài)的節(jié)點(沒有綁定任何動態(tài)數(shù)據(jù)),
這樣就知道那部分不會變化,于是在頁面需要更新時,減少去比對這部分DOM
從而達到性能優(yōu)化的目的
比如這個模板span 和 b 就是靜態(tài)節(jié)點,在 optimize 處理中,就會給他們添加 static 判斷是否是靜態(tài)節(jié)點
{ static: false, staticRoot: false, tag: "div", children: [{ staticRoot: true, tag: "span", children: [{ static: true, tag: "b" }] },{ static: false, text: "{{a}}" }] }
而你也看到一個屬性,staticRoot,這個是表示這個節(jié)點是否是靜態(tài)根節(jié)點的意思
用來標(biāo)記 某部分靜態(tài)節(jié)點 最大的祖宗節(jié)點,后面更新的時候,只要碰到這個屬性,就知道他的所有子孫節(jié)點都是靜態(tài)節(jié)點了,而不需要每個子孫節(jié)點都要判斷一次浪費時間
具體是怎么做的,感興趣的話歡迎看以后的源碼版
Generate這是 compile 的第三步
作用是把前兩步生成完善的 ast 組裝成 render 字符串(這個 render 變成函數(shù)后是可執(zhí)行的函數(shù),不過現(xiàn)在是字符串的形態(tài),后面會轉(zhuǎn)成函數(shù))
看個例子經(jīng)過前兩步變成 ast
{ static: false, staticRoot: false, tag: "div", children: [{ static: false, staticRoot: false, tag: "span", children: [{ static: false, text: "{}" }] },{ static: false, text: "{{a}}" }] }
然后,generate 接收 ast,先處理最外層 ast,然后開始遞歸遍歷子節(jié)點,直到所有節(jié)點被處理完
這個過程中,字符串會被一點一點拼接完成,比如上面的 ast 拼接結(jié)果就是下面這樣
_c 是生成節(jié)點對應(yīng)的 Vnode 的一個函數(shù)
` _c("div", [ _c("span", [ _v(b) ]), _v(a) ]) `簡單說一下拼接流程
1、一開始接收到 ast,處理最外層 ast 這個點,是 div,于是拼接得到字符串
code = ` _c("div", [ `
2、遍歷 div 子節(jié)點,遇到 span,拼接在 div 的子節(jié)點數(shù)組中
code = `_c("div", [ _c("span", [ `
3、開始處理 span 的子節(jié)點 b,放進 span 的 子節(jié)點數(shù)組中
code = ` _c("div", [ _c("span", [ _v(b) `
4、span 子節(jié)點處理完,閉合 span 的 子節(jié)點數(shù)組
code = ` _c("div", [ _c("span", [ _v(b) ] `
5、繼續(xù)處理 span 同級 的子節(jié)點,是個文本節(jié)點,但是是動態(tài)值,變量是 a
code = `_c("div", [ _c("span", [ _v(b) ] , _v(a) `
6、所有子節(jié)點都處理完畢,閉合 div 的 子節(jié)點數(shù)組
code = ` _c("div", [ _c("span", [ _v(b) ] , _v(a) )] `render轉(zhuǎn)成函數(shù)
前面兩步把 template 解析生成了 render 字符串,但是需要執(zhí)行的話,還是需要轉(zhuǎn)換成函數(shù)的
怎么轉(zhuǎn)呢?就是下面這樣
render = new Function(render)
然后 render 保存在實例上,具體位置是
vm.$options.render
至此,compile 所有的功能就完成了
而關(guān)于 render 的內(nèi)容,比如說 render 中出現(xiàn)的各種函數(shù)是什么,會專門放在 render 的文章去記錄
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/106566.html
摘要:當(dāng)字符串開頭是時,可以匹配匹配尾標(biāo)簽。從結(jié)尾,找到所在位置批量閉合。 寫文章不容易,點個贊唄兄弟 專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請點擊 下面鏈接 或者 拉到 下面關(guān)注公眾號也可以吧 【Vue原理】Compile - 源碼版 之 標(biāo)簽解析...
寫文章不容易,點個贊唄兄弟 專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺得排版難看,請點擊 下面鏈接 或者 拉到 下面關(guān)注公眾號也可以吧 【Vue原理】Compile - 源碼版 之 Parse 主要流程 本文難度較繁瑣,需要耐心觀看,如果你對 compile 源碼暫時...
摘要:頁面這個實例,按理就需要解析兩次,但是有緩存之后就不會理清思路也就是說,其實內(nèi)核就是不過是經(jīng)過了兩波包裝的第一波包裝在中的內(nèi)部函數(shù)中內(nèi)部函數(shù)的作用是合并公共和自定義,但是相關(guān)代碼已經(jīng)省略,另一個就是執(zhí)行第二波包裝在中,目的是進行緩存 寫文章不容易,點個贊唄兄弟 專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 ...
摘要:還原的難度就在于變成模板了,因為其他的什么等是原封不動的哈哈,可是直接照抄最后鑒于本人能力有限,難免會有疏漏錯誤的地方,請大家多多包涵,如果有任何描述不當(dāng)?shù)牡胤?,歡迎后臺聯(lián)系本人,有重謝 寫文章不容易,點個贊唄兄弟 專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于 Vue版本 【2.5.17】 如果你覺得排版...
摘要:寫文章不容易,點個贊唄兄弟專注源碼分享,文章分為白話版和源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究基于版本如果你覺得排版難看,請點擊下面鏈接或者拉到下面關(guān)注公眾號也可以吧原理源碼版之節(jié)點數(shù)據(jù)拼接上一篇我們 寫文章不容易,點個贊唄兄弟 專注 Vue 源碼分享,文章分為白話版和 源碼版,白話版助于理解工作原理,源碼版助于了解內(nèi)部詳情,讓我們一起學(xué)習(xí)吧研究...
閱讀 2205·2021-09-27 14:04
閱讀 1941·2019-08-30 15:55
閱讀 1762·2019-08-30 13:13
閱讀 1128·2019-08-30 13:07
閱讀 2801·2019-08-29 15:20
閱讀 3295·2019-08-29 12:42
閱讀 3396·2019-08-28 17:58
閱讀 3675·2019-08-28 17:56