<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
繼上篇文章:
parseHTML 函數原始碼解析
var startTagMatch = parseStartTag(); if (startTagMatch) { handleStartTag(startTagMatch); if (shouldIgnoreFirstNewline(startTagMatch.tagName, html)) { advance(1); } continue }
在上個章節中知道startTagMatch 就是獲取parseStartTag函數的返回值。並只有在成功匹配到開始標籤的情況下parseStartTag 才會返回解析結果(一個物件),否則返回undefined。
假設有如下html(template)字串:
<div id="box" v-if="watings"></div>
則parseStartTag函數的返回值如下:
match = { tagName: 'div', attrs: [ [ 'id="box"', 'id', '=', 'box', undefined, undefined ], [ ' v-if="watings"', 'v-if', '=', 'watings', undefined, undefined ] ], start: index, unarySlash: undefined, end: index }
現在我們假設匹配成功,那麼if語句塊中的程式碼將會被執行,此時會將解析結果作為引數傳遞給 handleStartTag 函數,handleStartTag原始碼如下:
function handleStartTag(match) { var tagName = match.tagName; var unarySlash = match.unarySlash; if (expectHTML) { if (lastTag === 'p' && isNonPhrasingTag(tagName)) { parseEndTag(lastTag); } if (canBeLeftOpenTag$$1(tagName) && lastTag === tagName) { parseEndTag(tagName); } } var unary = isUnaryTag$$1(tagName) || !!unarySlash; var l = match.attrs.length; var attrs = new Array(l); for (var i = 0; i < l; i++) { var args = match.attrs[i]; var value = args[3] || args[4] || args[5] || ''; var shouldDecodeNewlines = tagName === 'a' && args[1] === 'href' ? options.shouldDecodeNewlinesForHref : options.shouldDecodeNewlines; attrs[i] = { name: args[1], value: decodeAttr(value, shouldDecodeNewlines) }; } if (!unary) { stack.push({ tag: tagName, lowerCasedTag: tagName.toLowerCase(), attrs: attrs }); lastTag = tagName; } if (options.start) { options.start(tagName, attrs, unary, match.start, match.end); } }
handleStartTag函數用來處理開始標籤的解析結果,所以它接收parseStartTag函數的返回值作為引數。handleStartTag函數的一開始定義兩個常數:tagName 以及 unarySlash:
var tagName = match.tagName; var unarySlash = match.unarySlash;
根據上章節的內容就能理解,tagName 儲存解析開始標籤的標籤名,unarySlash 可以根據他的值判斷是解析的開始標籤是否為一元標籤。
接著是一個if語句塊,if語句的判斷條件是if (expectHTML),前面說過expectHTML 是parser選項,是一個布林值,如果為真則該 if 語句塊的程式碼將被執行。但是現在我們暫時不看這段程式碼,因為這段程式碼包含 parseEndTag 函數的呼叫,所以待我們講解完 parseEndTag 函數之後,再回頭來說這段程式碼。
在往下定義了三個變數:
var unary = isUnaryTag$$1(tagName) || !!unarySlash; var l = match.attrs.length; var attrs = new Array(l);
變數 unary 是一個布林值,當它為真時代表著標籤是一元標籤,否則是二元標籤。
他們通過isUnaryTag來判斷,其原理通過傳遞的標籤名判斷是否有跟預設標準HTML中規定的那些一元標籤一致。
l 和 attrs ,其中常數 l 的值儲存著 match.attrs 陣列的長度,而 attrs 常數則是一個與match.attrs陣列長度相等的陣列。
這兩個常數將被用於接下來的for迴圈中:
for (var i = 0; i < l; i++) { var args = match.attrs[i]; var value = args[3] || args[4] || args[5] || ''; var shouldDecodeNewlines = tagName === 'a' && args[1] === 'href' ? options.shouldDecodeNewlinesForHref : options.shouldDecodeNewlines; attrs[i] = { name: args[1], value: decodeAttr(value, shouldDecodeNewlines) }; }
具體看一下回圈體的程式碼,首先定義 args 常數,它的值就是每個屬性的解析結果,即match.attrs 陣列中的元素物件。
變數 value 中就儲存著最終的屬性值,如果第4、5、6 項都沒有獲取到屬性值,那麼屬性值將被設定為一個空字串:''。
屬性值獲取到了之後,就可以拼裝最終的 attrs 陣列。
attrs 陣列的每個元素物件只包含兩個元素,即屬性名 name 和屬性值 value ,對於屬性名直接從 args[1] 中即可獲取,但我們發現屬性值卻沒有直接使用前面獲取到的 value ,而是將傳value 遞給了decodeAttr 函數,並使用該函數的返回值作為最終的屬性值。
decodeAttr 函數的作用是對屬性值中所包含的 html 實體進行解碼,將其轉換為實體對應的字元。關於 shouldDecodeNewlinesForHref 與 shouldDecodeNewlines 可回顧章節
Vue編譯器原始碼分析compileToFunctions作用
接下來是:
if (!unary) { stack.push({ tag: tagName, lowerCasedTag: tagName.toLowerCase(), attrs: attrs }); lastTag = tagName; }
這個if條件是當開始標籤是非一元標籤時才會執行,其目的是: 如果開始標籤是非一元標籤,則將該開始標籤的資訊入棧,即push到stack陣列中,並將lastTag的值設定為該標籤名。
在講解 parseHTML 函數開頭定義的變數和常數的過程中,我們講解過 stack 常數以及lastTage 變數,其目的是將來判斷是否缺少閉合標籤,並且現在大家應該知道為什麼 lastTag 所儲存的標籤名字始終儲存著 stack 棧頂的元素了。
最後一段程式碼呼叫parser勾點函數的:
if (options.start) { options.start(tagName, attrs, unary, match.start, match.end); }
如果 parser 選項中包含 options.start 函數,則呼叫之,並將開始標籤的名字 tagName ,格式化後的屬性陣列 attrs ,是否為一元標籤 unary ,以及開始標籤在原 html 中的開始和結束位置match.start 和 match.end 作為引數傳遞。
接下來我們分析 parse 到結束標籤之後會怎麼做。
以上就是vue parseHTML 函數原始碼解析的詳細內容,更多關於vue parseHTML 函數的資料請關注it145.com其它相關文章!
相關文章
<em>Mac</em>Book项目 2009年学校开始实施<em>Mac</em>Book项目,所有师生配备一本<em>Mac</em>Book,并同步更新了校园无线网络。学校每周进行电脑技术更新,每月发送技术支持资料,极大改变了教学及学习方式。因此2011
2021-06-01 09:32:01
综合看Anker超能充系列的性价比很高,并且与不仅和iPhone12/苹果<em>Mac</em>Book很配,而且适合多设备充电需求的日常使用或差旅场景,不管是安卓还是Switch同样也能用得上它,希望这次分享能给准备购入充电器的小伙伴们有所
2021-06-01 09:31:42
除了L4WUDU与吴亦凡已经多次共事,成为了明面上的厂牌成员,吴亦凡还曾带领20XXCLUB全队参加2020年的一场音乐节,这也是20XXCLUB首次全员合照,王嗣尧Turbo、陈彦希Regi、<em>Mac</em> Ova Seas、林渝植等人全部出场。然而让
2021-06-01 09:31:34
目前应用IPFS的机构:1 谷歌<em>浏览器</em>支持IPFS分布式协议 2 万维网 (历史档案博物馆)数据库 3 火狐<em>浏览器</em>支持 IPFS分布式协议 4 EOS 等数字货币数据存储 5 美国国会图书馆,历史资料永久保存在 IPFS 6 加
2021-06-01 09:31:24
开拓者的车机是兼容苹果和<em>安卓</em>,虽然我不怎么用,但确实兼顾了我家人的很多需求:副驾的门板还配有解锁开关,有的时候老婆开车,下车的时候偶尔会忘记解锁,我在副驾驶可以自己开门:第二排设计很好,不仅配置了一个很大的
2021-06-01 09:30:48
不仅是<em>安卓</em>手机,苹果手机的降价力度也是前所未有了,iPhone12也“跳水价”了,发布价是6799元,如今已经跌至5308元,降价幅度超过1400元,最新定价确认了。iPhone12是苹果首款5G手机,同时也是全球首款5nm芯片的智能机,它
2021-06-01 09:30:45