最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

vue?parseHTML?函數(shù)源碼解析

 更新時(shí)間:2022年07月13日 16:51:40   作者:李李  
這篇文章主要為大家介紹了vue?parseHTML函數(shù)的源碼解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

正文

接上篇:

Vue編譯器源碼分析AST 抽象語(yǔ)法樹(shù)

function parseHTML(html, options) {
	var stack = [];
	var expectHTML = options.expectHTML;
	var isUnaryTag$$1 = options.isUnaryTag || no;
	var canBeLeftOpenTag$$1 = options.canBeLeftOpenTag || no;
	var index = 0;
	var last, lastTag;
	// 開(kāi)啟一個(gè) while 循環(huán),循環(huán)結(jié)束的條件是 html 為空,即 html 被 parse 完畢
	while (html) {
		last = html;
		if (!lastTag || !isPlainTextElement(lastTag)) {
			// 確保即將 parse 的內(nèi)容不是在純文本標(biāo)簽里 (script,style,textarea)
		} else {
			// parse 的內(nèi)容是在純文本標(biāo)簽里 (script,style,textarea)
		}
		//將整個(gè)字符串作為文本對(duì)待
		if (html === last) {
			options.chars && options.chars(html);
			if (!stack.length && options.warn) {
				options.warn(("Mal-formatted tag at end of template: \"" + html + "\""));
			}
			break
		}
	}
	// Clean up any remaining tags
	parseEndTag();
	function advance(n) {
		index += n;
		html = html.substring(n);
	}
	//parse 開(kāi)始標(biāo)簽
	function parseStartTag() {
		//...
	}
	//處理 parseStartTag 的結(jié)果
	function handleStartTag(match) {
		//...
	}
	//parse 結(jié)束標(biāo)簽
	function parseEndTag(tagName, start, end) {
		//...
	}
}

可以看到 parseHTML 函數(shù)接收兩個(gè)參數(shù):html 和 options ,其中 html 是要被編譯的字符串,而options則是編譯器所需的選項(xiàng)。

整體上來(lái)講 parseHTML分為三部分。

  • 函數(shù)開(kāi)頭定義的一些常量和變量
  • while 循環(huán)
  • parse 過(guò)程中需要用到的 analytic function

函數(shù)開(kāi)頭定義的一些常量和變量

先從第一部分開(kāi)始講起

var stack = [];
var expectHTML = options.expectHTML;
var isUnaryTag$$1 = options.isUnaryTag || no;
var canBeLeftOpenTag$$1 = options.canBeLeftOpenTag || no;
var index = 0;
var last, lastTag;

第一個(gè)變量是 stack,它被初始化為一個(gè)空數(shù)組,在 while 循環(huán)中處理 html 字符流的時(shí)候每當(dāng)遇到一個(gè)非單標(biāo)簽,都會(huì)將該開(kāi)始標(biāo)簽 push 到該數(shù)組。它的作用模板中 DOM 結(jié)構(gòu)規(guī)范性的檢測(cè)。

但在一個(gè) html 字符串中,如何判斷一個(gè)非單標(biāo)簽是否缺少結(jié)束標(biāo)簽?zāi)兀?/p>

假設(shè)我們有如下html字符串:

<div><p><span></p></div>

在編譯這個(gè)字符串的時(shí)候,首先會(huì)遇到 div 開(kāi)始標(biāo)簽,并將該 push 到 stack 數(shù)組,然后會(huì)遇到 p 開(kāi)始標(biāo)簽,并將該標(biāo)簽 push 到 stack ,接下來(lái)會(huì)遇到 span 開(kāi)始標(biāo)簽,同樣被 push 到 stack ,此時(shí) stack 數(shù)組內(nèi)包含三個(gè)元素。

再然后便會(huì)遇到 p 結(jié)束標(biāo)簽,按照正常邏輯可以推理出最先遇到的結(jié)束標(biāo)簽,其對(duì)應(yīng)的開(kāi)始標(biāo)簽應(yīng)該最后被push到 stack 中,也就是說(shuō) stack 棧頂?shù)脑貞?yīng)該是 span ,如果不是 span 而是 p,這說(shuō)明 span 元素缺少閉合標(biāo)簽。

這就是檢測(cè) html 字符串中是否缺少閉合標(biāo)簽的原理。

第二個(gè)變量是 expectHTML,它的值被初始化為 options.expectHTML,也就是編譯器選項(xiàng)中的 expectHTML。

第三個(gè)常量是 isUnaryTag,用來(lái)檢測(cè)一個(gè)標(biāo)簽是否是一元標(biāo)簽。

第四個(gè)常量是 canBeLeftOpenTag,用來(lái)檢測(cè)一個(gè)標(biāo)簽是否是可以省略閉合標(biāo)簽的非一元標(biāo)簽。

  • index 初始化為 0 ,標(biāo)識(shí)著當(dāng)前字符流的讀入位置。
  • last 存儲(chǔ)剩余還未編譯的 html 字符串。
  • lastTag 始終存儲(chǔ)著位于 stack 棧頂?shù)脑亍?/li>

while 循環(huán)

接下來(lái)將進(jìn)入第二部分,即開(kāi)啟一個(gè) while 循環(huán),循環(huán)的終止條件是 html 字符串為空,即html 字符串全部編譯完畢。

while (html) {
	last = html;
	// Make sure we're not in a plaintext content element like script/style
	if (!lastTag || !isPlainTextElement(lastTag)) {
		var textEnd = html.indexOf('<');
		if (textEnd === 0) {
			// Comment:
			if (comment.test(html)) {
				var commentEnd = html.indexOf('-->');
				if (commentEnd >= 0) {
					if (options.shouldKeepComment) {
						options.comment(html.substring(4, commentEnd));
					}
					advance(commentEnd + 3);
					continue
				}
			}
			// http://en.wikipedia.org/wiki/Conditional_comment#Downlevel-revealed_conditional_comment
			if (conditionalComment.test(html)) {
				var conditionalEnd = html.indexOf(']>');
				if (conditionalEnd >= 0) {
					advance(conditionalEnd + 2);
					continue
				}
			}
			// Doctype:
			var doctypeMatch = html.match(doctype);
			if (doctypeMatch) {
				advance(doctypeMatch[0].length);
				continue
			}
			// End tag:
			var endTagMatch = html.match(endTag);
			if (endTagMatch) {
				var curIndex = index;
				advance(endTagMatch[0].length);
				parseEndTag(endTagMatch[1], curIndex, index);
				continue
			}
			// Start tag:
			var startTagMatch = parseStartTag();
			if (startTagMatch) {
				handleStartTag(startTagMatch);
				if (shouldIgnoreFirstNewline(startTagMatch.tagName, html)) {
					advance(1);
				}
				continue
			}
		}
		var text = (void 0),
			rest = (void 0),
			next = (void 0);
		if (textEnd >= 0) {
			rest = html.slice(textEnd);
			while (
				!endTag.test(rest) &&
				!startTagOpen.test(rest) &&
				!comment.test(rest) &&
				!conditionalComment.test(rest)
			) {
				// < in plain text, be forgiving and treat it as text
				next = rest.indexOf('<', 1);
				if (next < 0) {
					break
				}
				textEnd += next;
				rest = html.slice(textEnd);
			}
			text = html.substring(0, textEnd);
			advance(textEnd);
		}
		if (textEnd < 0) {
			text = html;
			html = '';
		}
		if (options.chars && text) {
			options.chars(text);
		}
	} else {
		var endTagLength = 0;
		var stackedTag = lastTag.toLowerCase();
		var reStackedTag = reCache[stackedTag] || (reCache[stackedTag] = new RegExp('([\\s\\S]*?)(</' + stackedTag +
			'[^>]*>)', 'i'));
		var rest$1 = html.replace(reStackedTag, function(all, text, endTag) {
			endTagLength = endTag.length;
			if (!isPlainTextElement(stackedTag) && stackedTag !== 'noscript') {
				text = text
					.replace(/<!\--([\s\S]*?)-->/g, '$1') // #7298
					.replace(/<!\[CDATA\[([\s\S]*?)]]>/g, '$1');
			}
			if (shouldIgnoreFirstNewline(stackedTag, text)) {
				text = text.slice(1);
			}
			if (options.chars) {
				options.chars(text);
			}
			return ''
		});
		index += html.length - rest$1.length;
		html = rest$1;
		parseEndTag(stackedTag, index - endTagLength, index);
	}
	if (html === last) {
		options.chars && options.chars(html);
		if (!stack.length && options.warn) {
			options.warn(("Mal-formatted tag at end of template: \"" + html + "\""));
		}
		break
	}
}

首先將在每次循環(huán)開(kāi)始時(shí)將 html 的值賦給變量 last :

last = html;

為什么這么做?在 while 循環(huán)即將結(jié)束的時(shí)候,有一個(gè)對(duì) last 和 html 這兩個(gè)變量的比較,在此可以找到答案:

if (html === last) {}

如果兩者相等,則說(shuō)明html 在經(jīng)歷循環(huán)體的代碼之后沒(méi)有任何改變,此時(shí)會(huì)"Mal-formatted tag at end of template: \"" + html + "\"" 錯(cuò)誤信息提示。

接下來(lái)可以簡(jiǎn)單看下整體while循環(huán)的結(jié)構(gòu)。

while (html) {
  last = html
  if (!lastTag || !isPlainTextElement(lastTag)) {
    // parse 的內(nèi)容不是在純文本標(biāo)簽里
  } else {
    // parse 的內(nèi)容是在純文本標(biāo)簽里 (script,style,textarea)
  }
  // 極端情況下的處理
  if (html === last) {
    options.chars && options.chars(html)
    if (process.env.NODE_ENV !== 'production' && !stack.length && options.warn) {
      options.warn(`Mal-formatted tag at end of template: "${html}"`)
    }
    break
  }
}

接下來(lái)我們重點(diǎn)來(lái)分析這個(gè)if else 中的代碼。

!lastTag || !isPlainTextElement(lastTag)

lastTag 剛剛講到它會(huì)一直存儲(chǔ) stack 棧頂?shù)脑?,但是?dāng)編譯器剛開(kāi)始工作時(shí),他只是一個(gè)空數(shù)組對(duì)象,![] == false

isPlainTextElement(lastTag) 檢測(cè) lastTag 是否為純標(biāo)簽內(nèi)容。

var isPlainTextElement = makeMap('script,style,textarea', true);

lastTag 為空數(shù)組 ,isPlainTextElement(lastTag ) 返回false, !isPlainTextElement(lastTag) ==true, 有興趣的同學(xué)可以閱讀下 makeMap 源碼。

接下來(lái)我們繼續(xù)往下看,簡(jiǎn)化版的代碼。

if (!lastTag || !isPlainTextElement(lastTag)) {
  var textEnd = html.indexOf('<')
  if (textEnd === 0) {
    // 第一個(gè)字符就是(<)尖括號(hào)
  }
 var text = (void 0),
     rest = (void 0),
     next = (void 0);
  if (textEnd >= 0) {
    //第一個(gè)字符不是(<)尖括號(hào)
  }
  if (textEnd < 0) {
    // 第一個(gè)字符不是(<)尖括號(hào)
  }
  if (options.chars && text) {
    options.chars(text)
  }
} else {
  // 省略 ...
}

textEnd ===0

當(dāng) textEnd === 0 時(shí),說(shuō)明 html 字符串的第一個(gè)字符就是左尖括號(hào),比如 html 字符串為:<div>box</div>,那么這個(gè)字符串的第一個(gè)字符就是左尖括號(hào)(<)。

if (textEnd === 0) {
	// Comment: 如果是注釋節(jié)點(diǎn)
	if (comment.test(html)) {
		var commentEnd = html.indexOf('-->');
		if (commentEnd >= 0) {
			if (options.shouldKeepComment) {
				options.comment(html.substring(4, commentEnd));
			}
			advance(commentEnd + 3);
			continue
		}
	}
	//如果是條件注釋節(jié)點(diǎn)
	if (conditionalComment.test(html)) {
		var conditionalEnd = html.indexOf(']>');
		if (conditionalEnd >= 0) {
			advance(conditionalEnd + 2);
			continue
		}
	}
	// 如果是 Doctyp節(jié)點(diǎn) 
	var doctypeMatch = html.match(doctype);
	if (doctypeMatch) {
		advance(doctypeMatch[0].length);
		continue
	}
	// End tag:  結(jié)束標(biāo)簽
	var endTagMatch = html.match(endTag);
	if (endTagMatch) {
		var curIndex = index;
		advance(endTagMatch[0].length);
		parseEndTag(endTagMatch[1], curIndex, index);
		continue
	}
	// Start tag: 開(kāi)始標(biāo)簽
	var startTagMatch = parseStartTag();
	if (startTagMatch) {
		handleStartTag(startTagMatch);
		if (shouldIgnoreFirstNewline(startTagMatch.tagName, html)) {
			advance(1);
		}
		continue
	}
}

細(xì)枝末節(jié)我們不看,重點(diǎn)在End tag 、 Start tag 上。

我們先從解析標(biāo)簽開(kāi)始分析

var startTagMatch = parseStartTag();
if (startTagMatch) {
	handleStartTag(startTagMatch);
	if (shouldIgnoreFirstNewline(startTagMatch.tagName, html)) {
		advance(1);
	}
	continue
}

parseStartTag 函數(shù)解析開(kāi)始標(biāo)簽

解析開(kāi)始標(biāo)簽會(huì)調(diào)用parseStartTag函數(shù),如果有返回值,說(shuō)明開(kāi)始標(biāo)簽解析成功。

function parseStartTag() {
	var start = html.match(startTagOpen);
	if (start) {
		var match = {
			tagName: start[1],
			attrs: [],
			start: index
		};
		advance(start[0].length);
		var end, attr;
		while (!(end = html.match(startTagClose)) &amp;&amp; (attr = html.match(attribute))) {
			advance(attr[0].length);
			match.attrs.push(attr);
		}
		if (end) {
			match.unarySlash = end[1];
			advance(end[0].length);
			match.end = index;
			return match
		}
	}
}

parseStartTag 函數(shù)首先會(huì)調(diào)用 html 字符串的 match 函數(shù)匹配 startTagOpen 正則,前面我們分析過(guò)編譯器所需的正則。

Vue編譯器token解析規(guī)則-正則分析

如果匹配成功,那么start 將是一個(gè)包含兩個(gè)元素的數(shù)組:第一個(gè)元素是標(biāo)簽的開(kāi)始部分(包含< 和 標(biāo)簽名稱);第二個(gè)元素是捕獲組捕獲到的標(biāo)簽名稱。比如有如下template:

<div></div>

start為:

start = ['&lt;div', 'div']

接下來(lái):

定義了 match 變量,它是一個(gè)對(duì)象,初始狀態(tài)下?lián)碛腥齻€(gè)屬性:

  • tagName:它的值為 start[1] 即標(biāo)簽的名稱。
  • attrs :這個(gè)數(shù)組就是用來(lái)存儲(chǔ)將來(lái)被匹配到的屬性。
  • start:初始值為 index,是當(dāng)前字符流讀入位置在整個(gè) html 字符串中的相對(duì)位置。
advance(start[0].length);

相對(duì)就比較簡(jiǎn)單了,他的作用就是在源字符中截取已經(jīng)編譯完成的字符,我們知道當(dāng)html 字符為 “”,整個(gè)詞法分析的工作就結(jié)束了,在這中間扮演重要角色的就是advance方法。

function advance(n) {
	index += n;
	html = html.substring(n);
}

接下來(lái):

var end, attr;
while (!(end = html.match(startTagClose)) &amp;&amp; (attr = html.match(attribute))) {
	advance(attr[0].length);
	match.attrs.push(attr);
}
if (end) {
	match.unarySlash = end[1];
	advance(end[0].length);
	match.end = index;
	return match
  }
}

主要看while循環(huán),循環(huán)的條件有兩個(gè),第一個(gè)條件是:沒(méi)有匹配到開(kāi)始標(biāo)簽的結(jié)束部分,這個(gè)條件的實(shí)現(xiàn)方式主要使用了 startTagClose 正則,并將結(jié)果保存到 end 變量中。

第二個(gè)條件是:匹配到了屬性,主要使用了attribute正則。

總結(jié)下這個(gè)while循環(huán)成立要素:沒(méi)有匹配到開(kāi)始標(biāo)簽的結(jié)束部分,并且匹配到了開(kāi)始標(biāo)簽中的屬性,這個(gè)時(shí)候循環(huán)體將被執(zhí)行,直到遇到開(kāi)始標(biāo)簽的結(jié)束部分為止。

接下來(lái)在循環(huán)體內(nèi)做了兩件事,首先調(diào)用advance函數(shù),參數(shù)為attr[0].length即整個(gè)屬性的長(zhǎng)度。然后會(huì)將此次循環(huán)匹配到的結(jié)果push到前面定義的match對(duì)象的attrs數(shù)組中。

advance(attr[0].length);
match.attrs.push(attr);

接下來(lái)看下最后這部分代碼。

if (end) {
	match.unarySlash = end[1];
	advance(end[0].length);
	match.end = index;
	return match
}

首先判斷了變量 end 是否為真,我們知道,即使匹配到了開(kāi)始標(biāo)簽的開(kāi)始部分以及屬性部分但是卻沒(méi)有匹配到開(kāi)始標(biāo)簽的結(jié)束部分,這說(shuō)明這根本就不是一個(gè)開(kāi)始標(biāo)簽。所以只有當(dāng)變量end存在,即匹配到了開(kāi)始標(biāo)簽的結(jié)束部分時(shí),才能說(shuō)明這是一個(gè)完整的開(kāi)始標(biāo)簽。

如果變量end的確存在,那么將會(huì)執(zhí)行 if 語(yǔ)句塊內(nèi)的代碼,不過(guò)我們需要先了解一下變量end的值是什么?

比如當(dāng)html(template)字符串如下時(shí):

<br />

那么匹配到的end的值為:

end = ['/>', '/']

比如當(dāng)html(template)字符串如下時(shí):

<div></div>

那么匹配到的end的值為:

end = ['>', undefined]

結(jié)論如果end[1]不為undefined,那么說(shuō)明該標(biāo)簽是一個(gè)一元標(biāo)簽。

那么現(xiàn)在再看if語(yǔ)句塊內(nèi)的代碼,將很容易理解,首先在match對(duì)象上添加unarySlash屬性,其值為end[1]

match.unarySlash = end[1];

然后調(diào)用advance函數(shù),參數(shù)為end[0].length,接著在match 對(duì)象上添加了一個(gè)end屬性,它的值為index,注意由于先調(diào)用的advance函數(shù),所以此時(shí)的index已經(jīng)被更新了。最后將match 對(duì)象作為 parseStartTag 函數(shù)的返回值返回。

只有當(dāng)變量end存在時(shí),即能夠確定確實(shí)解析到了一個(gè)開(kāi)始標(biāo)簽的時(shí)候parseStartTag函數(shù)才會(huì)有返回值,并且返回值是match對(duì)象,其他情況下parseStartTag全部返回undefined。

總結(jié):

我們模擬假設(shè)有如下html(template)字符串:

<div id="box" v-if="watings"></div>

則parseStartTag函數(shù)的返回值如下:

match = {
  tagName: 'div',
  attrs: [
    [
      'id="box"',
      'id',
      '=',
      'box',
      undefined,
      undefined
    ],
    [
      ' v-if="watings"',
      'v-if',
      '=',
      'watings',
      undefined,
      undefined
    ]
  ],
  start: index,
  unarySlash: undefined,
  end: index
}

我們講解完了parseStartTag函數(shù)及其返回值,現(xiàn)在我們回到對(duì)開(kāi)始標(biāo)簽的 parse 部分,接下來(lái)我們會(huì)繼續(xù)講解,拿到返回值之后的處理。

var startTagMatch = parseStartTag();
if (startTagMatch) {
	handleStartTag(startTagMatch);
	if (shouldIgnoreFirstNewline(startTagMatch.tagName, html)) {
		advance(1);
	}
	continue
}

篇幅有限請(qǐng)移步:

parseHTML 函數(shù)源碼解析返回值后的處理

以上就是vue parseHTML 函數(shù)源碼解析的詳細(xì)內(nèi)容,更多關(guān)于vue parseHTML函數(shù)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • Vue之定義全局工具類問(wèn)題

    Vue之定義全局工具類問(wèn)題

    這篇文章主要介紹了Vue之定義全局工具類問(wèn)題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • vue計(jì)算屬性+vue中class與style綁定(推薦)

    vue計(jì)算屬性+vue中class與style綁定(推薦)

    這篇文章主要介紹了vue計(jì)算屬性+vue中class與style綁定,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2020-03-03
  • vue-cli history模式實(shí)現(xiàn)tomcat部署報(bào)404的解決方式

    vue-cli history模式實(shí)現(xiàn)tomcat部署報(bào)404的解決方式

    這篇文章主要介紹了vue-cli history模式實(shí)現(xiàn)tomcat部署報(bào)404的解決方式,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-09-09
  • Vue?el-table實(shí)現(xiàn)右鍵菜單功能

    Vue?el-table實(shí)現(xiàn)右鍵菜單功能

    這篇文章主要為大家詳細(xì)介紹了Vue?el-table實(shí)現(xiàn)右鍵菜單功能,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-04-04
  • 詳解Vue源碼學(xué)習(xí)之雙向綁定

    詳解Vue源碼學(xué)習(xí)之雙向綁定

    這篇文章主要介紹了Vue源碼學(xué)習(xí)之雙向綁定,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-04-04
  • Vue3?中實(shí)現(xiàn)元素拖拽功能

    Vue3?中實(shí)現(xiàn)元素拖拽功能

    這篇文章主要介紹了在Vue3中實(shí)現(xiàn)飄逸的元素拖拽,在本次案例中需要認(rèn)真思考對(duì)應(yīng)的幾個(gè)坐標(biāo)和移動(dòng)時(shí)坐標(biāo)如何更新,事件的使用要成對(duì)出現(xiàn),如何在這個(gè)拖拽的 Icon 上增加點(diǎn)擊事件時(shí)還需要多做一些處理,需要的朋友可以參考下
    2023-07-07
  • Vue項(xiàng)目中在父組件中直接調(diào)用子組件的方法

    Vue項(xiàng)目中在父組件中直接調(diào)用子組件的方法

    這篇文章主要給大家介紹了Vue項(xiàng)目中如何在父組件中直接調(diào)用子組件的方法,文章通過(guò)代碼示例介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下
    2023-11-11
  • Vue數(shù)據(jù)雙向綁定原理實(shí)例解析

    Vue數(shù)據(jù)雙向綁定原理實(shí)例解析

    這篇文章主要介紹了Vue數(shù)據(jù)雙向綁定原理實(shí)例解析,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下
    2020-05-05
  • vue3.0手動(dòng)封裝分頁(yè)組件的方法

    vue3.0手動(dòng)封裝分頁(yè)組件的方法

    這篇文章主要為大家詳細(xì)介紹了vue3.0手動(dòng)封裝分頁(yè)組件的方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-09-09
  • Vue下拉選擇框Select組件使用詳解(一)

    Vue下拉選擇框Select組件使用詳解(一)

    這篇文章主要為大家詳細(xì)介紹了Vue下拉選擇框Select組件的使用,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-03-03

最新評(píng)論

葵青区| 确山县| 比如县| 台湾省| 会东县| 双牌县| 密云县| 黄石市| 侯马市| 清镇市| 晋中市| 浙江省| 祥云县| 长治市| 咸丰县| 通州市| 芒康县| 灵丘县| 界首市| 夏邑县| 南木林县| 靖安县| 台北市| 阿鲁科尔沁旗| 南开区| 辽阳县| 雅江县| 谢通门县| 文昌市| 榆林市| 油尖旺区| 荆门市| 上犹县| 社旗县| 潍坊市| 胶州市| 双辽市| 如东县| 武陟县| 宁国市| 扶余县|