您好,登錄后才能下訂單哦!
今天小編給大家分享一下vue parseHTML函數拿到返回值后怎么處理的相關知識點,內容詳細,邏輯清晰,相信大部分人都還太了解這方面的知識,所以分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后有所收獲,下面我們一起來了解一下吧。
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 作為參數傳遞。
以上就是“vue parseHTML函數拿到返回值后怎么處理”這篇文章的所有內容,感謝各位的閱讀!相信大家閱讀完這篇文章都有很大的收獲,小編每天都會為大家更新不同的知識,如果還想學習更多的知識,請關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。