我愛學(xué)習(xí)網(wǎng)-上傳
當(dāng)前位置: 主頁 > 文庫 > Html/CSS >

parseHTML函數(shù)源碼解析

時(shí)間:2020-08-27 21:27來源:我愛學(xué)習(xí)網(wǎng) 作者:apple 點(diǎn)擊:

在正式扎進(jìn)Vue parse源碼之前,我們先了解下它周邊的工具函數(shù),這能幫我們快速的去理解閱讀。

 

還記得我們?cè)谏险鹿?jié)講的element元素節(jié)點(diǎn)的描述對(duì)象嗎?

var element = {
		type: 1,
  	tag: tag,
  	parent: null,
  	attrsList: attrs,
  	children: []
}

 

在源碼中定義了一個(gè)createASTElement函數(shù),用來創(chuàng)建一個(gè)元素的描述對(duì)象。

 

createASTElement函數(shù)

function createASTElement(tag, attrs, parent) {
		return {
    		type: 1,
      	tag: tag,
      	attrsList: attrs,
      	attrsMap: makeAttrsMap(attrs),
      	parent: parent,
      	children: []
    }
}

 

解析指令所用正則

var onRE = /^@|^v-on:/;
var dirRE = /^v-|^@|^:/;
var forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;
var forIteratorRE = /,([^,\}\]]*)(?:,([^,\]\]]*))?$/;
var stripParensRE = /^\(|\)$/g;

var argRE = /:(.*)$/;
var bindRE = /^:|^v-bind:/;
var modifierRE = /\.[^.]+/g;

 

在解析開始標(biāo)簽的時(shí)候你遇到的不僅有屬性,還有一些Vue自定義的指令。下面一起來分析下解析指令會(huì)有用哪些正則。

 

onRE

var onRE = /^@|^v-on:/;

 

匹配以字符@或v-on:開頭的字符串,主要作用是檢測(cè)標(biāo)簽屬性名是否是監(jiān)聽事件的指令。

 

dirRE

var cosnt dirRE = /^v-|^@|^:/

 

匹配以字符 v- 或 @或 : 開頭的字符串,主要作用是檢測(cè)標(biāo)簽屬性名是否是指令。在Vue中所有以 v- 開頭的屬性都被認(rèn)為是指令,另外@字符是 v-on 的縮寫,:字符是 v-bind 的縮寫。

 

forAliasRE

var forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;

 

匹配 v-for 屬性的值,并捕獲in 或 of 前后的字符串。都是正則大神就不需要解釋怎么捕獲了。

 

forIteratorRE

var forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/;

 

這個(gè)也是匹配 v-for 的屬性值,不過比之前要稍微復(fù)雜點(diǎn):列表渲染 v-for 需要先了解下這個(gè)

 


{{obj}}: {{index}}

{{index}}. {{name}}: {{value}}

 

沒錯(cuò)就是用來捕獲,實(shí)例1中的:'obj, index' ;實(shí)例2中的:'value, name, index'。

 

stripParensRE

var strpParensRE = /^\(|\)$/g;

 

這個(gè)捕獲組用來捕獲要么以字符(開頭,要么以字符)結(jié)尾的字符串,或者兩者都滿足。那么這個(gè)正則的作用是什么呢?我們?cè)谥v解這則forIteratorRE時(shí)有個(gè)細(xì)節(jié)不知道大家注意到了沒有,就是forITERatorRE正則所匹配的字符串是'obj, index',而不是'(obj, index)',這連個(gè)字符串的區(qū)別就在于第二個(gè)字符串擁有作用括號(hào),所以在使用forIteratorRE正則之前,需要使用stripParensRE正則去掉字符串'(obj, index)'中的作用括號(hào),實(shí)現(xiàn)方式很簡單:

"(obj, index)".replace(stripParensRE, "")

 

argRE

var argRE = /:(.*)$/;

 

argRE正則用來匹配指令編寫中的參數(shù),并且擁有一個(gè)捕獲組,用來捕獲參數(shù)的名字。

 

 v-on 為指令,click為傳遞給 v-on 指令的參數(shù),stop 為修飾符。

 

bindRE

var bindRE = /^:|^v-bind:/;

 

該正則用來匹配以字符 : 或字符串 v-bind: 開頭的字符串,主要用來檢測(cè)一個(gè)標(biāo)簽的屬性是否是綁定(v-bind)。

 

modifierRE

var modifierRE = /\.[^.]+/g;

 

該正則用來匹配修飾符的,但是并沒有捕獲任何東西,但你可以用match、exec等方法獲取與當(dāng)前正則匹配成功的信息。

 

parse函數(shù)中的變量

在講解parse函數(shù)直接我們還需要先了解下它內(nèi)部所定義的一些變量以及用途。

function parse(template, options) {
		warn$2 = options.warn || baseWarn;
  	
  	platformIsPreTag = options.isPreTag || no;
  	platformMustUserProp = options.mustUseProp || no;
  	platformGetTagNamespace = options.getTagNamespace || no;
  	
  	transforms = pluckModuleFunction(options.modules, 'transformNode');
  	preTransforms = pluckModuleFunction(options.modules, 'preTransformNode');
  	postTransforms = pluckModuleFunction(options.modules, 'postTransformNode');
  
  	delimiters = options.delimiters;
  
  	var stack = [];
  	var preserveWhitespace = options.preserveWhitespace !== false;
  	var root;
  	var currentParent;
  	var inVPre = false;
  	var inPre = false;
  	var warned = false;
  	
  	function warnOnce(msg) {
    	// ...
    }
  
  	function closeElement(element) {
    	// ...
    }
  	
  	parseHTML(template, {
    		warn: warn$2,
      	expectHTML: options.expectHTML,
      	isUnaryTag: options.isUnaryTag,
      	canBeLeftOpenTag: options.canBeLeftOpenTag,
      	shouldDecodeNewlines: options.shouldDecodeNewlines,
      	shouldDecodeNewlinesForHref: options.shouldDecodeNewlinesForHref,
      	shouldKeepComment: options.comments,
      	start: function start(tag, attrs, unary) {},
      	end: function end() {},
      	chars: function chars(text) {},
      	comment: function comment(text) {},
    });
  
  	return root;
}

 

我們先來看下針對(duì)web平臺(tái)初始化的一些變量。

warn$2 = options.warn || baseWarn;
  	
platformIsPreTag = options.isPreTag || no;
platformMustUserProp = options.mustUseProp || no;
platformGetTagNamespace = options.getTagNamespace || no;

transforms = pluckModuleFunction(options.modules, 'transformNode');
preTransforms = pluckModuleFunction(options.modules, 'preTransformNode');
postTransforms = pluckModuleFunction(options.modules, 'postTransformNode');

delimiters = options.delimiters;

 

  • warn$2 函數(shù) 毋庸置疑它的作用是用來打印警告信息的。
  • platformIsPreTag 函數(shù)是一個(gè)編譯器選擇,其作用是通過給定的標(biāo)簽名字判斷該標(biāo)簽是否是 pre 標(biāo)簽。
  • platfromMustUseProp 該函數(shù)也是一個(gè)編譯器選項(xiàng),其作用是用來檢測(cè)一個(gè)屬性在標(biāo)簽中是否要使用元素對(duì)象原生的 prop 進(jìn)行綁定。
  • platformGetTagNamespace 該函數(shù)是一個(gè)編譯器選項(xiàng),其作用是用來獲取元素(標(biāo)簽)的命名空間。
  • transforms、preTransfroms、postTransforms 還沒講到它們的上下文,暫時(shí)不解釋它們的作用。
  • delimiters 它的值為 options.delimiters 屬性,它的值就是在創(chuàng)建 Vue 實(shí)例對(duì)象時(shí)所傳遞的 delimiters 選項(xiàng)。

 

繼續(xù)往下看:

var stack = [];
var preserveWhitespace = options.preserveWhitespace !== false;
var root;
var currentParent;
var inVPre = false;
var inPre = false;
var warned = false;

 

  • stack 初始值是一個(gè)空數(shù)組,作用在上個(gè)章節(jié)我們講到,回退操作為了讓子元素描述對(duì)象的 parent 屬性能夠正確指向其父元素。
  • preserveWhitespace 是一個(gè)布爾值并且它的值與編譯器選擇中的options.preserveWhitespace選項(xiàng)有關(guān),只要options.preserveWhitespace的值不為false,那么preserveWhitespace的值就為true。其中options.preserveWhitespace選項(xiàng)用來告訴編譯器在編譯html字符串時(shí)是否放棄標(biāo)簽之間的空格,如果為 true 則代表放棄。
  • root 存儲(chǔ)最終生成的AST。
  • currentParent 通過上章節(jié)了解到,該變量維護(hù)元素描述對(duì)象之間的父子關(guān)系。
  • inVPre 初始值:false。標(biāo)識(shí)當(dāng)前解析的標(biāo)簽是否在擁有 v-pre 的標(biāo)簽之內(nèi)。
  • inPre 初始值:false。用來打印警告信息的函數(shù),只不過warnOnce函數(shù)就如它的名字一樣,只會(huì)打印一次警告信息,并且 warnOnce 函數(shù)也是通過調(diào)用 warn 函數(shù)來實(shí)現(xiàn)的。

 

好了一些邊邊角角的東西就先講到這,接下來我們一起來分析Vue parse源碼看看一棵完整的AST樹是如何構(gòu)建出來的。

 

------分隔線----------------------------
    ?分享到??
看看啦
主站蜘蛛池模板: 国产成人精品无人区一区 | 国产成人久久一区二区三区| 麻豆天美国产一区在线播放| 一区二区三区国模大胆| 亚洲愉拍一区二区三区| 亚洲av福利无码无一区二区 | 国产爆乳无码一区二区麻豆| 国产成人久久一区二区不卡三区| 亚洲无删减国产精品一区| 91在线精品亚洲一区二区| 日韩电影一区二区| 亚洲AV无码一区二区三区性色| 最新中文字幕一区| 亚洲成人一区二区| 91精品福利一区二区三区野战| 国产成人一区二区三区免费视频| 精品国产日韩亚洲一区| 亚洲视频一区在线观看| 无码人妻精品一区二区蜜桃百度| 国产成人精品无码一区二区| 丰满爆乳无码一区二区三区| 农村人乱弄一区二区 | 日韩精品一区二区三区四区 | 成人精品一区久久久久| 春暖花开亚洲性无区一区二区| 国产一区二区在线| 日本精品一区二区三本中文| 日韩在线视频一区| 一区二区三区视频免费| 久久精品国产一区二区三区| 中文字幕一区二区人妻性色| 国产亚洲无线码一区二区| 亚洲国产精品一区第二页| 精品人无码一区二区三区| 久久人妻无码一区二区| 国产在线视频一区二区三区| 亚洲成a人一区二区三区| 国99精品无码一区二区三区| 精品欧洲av无码一区二区三区| 国内自拍视频一区二区三区 | 中文字幕在线一区二区在线|