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

深入解析Vue 組件命名那些事

 更新時(shí)間:2017年07月18日 15:59:33   作者:jingsam  
本篇文章主要介紹了深入解析Vue 組件命名那些事,小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧

There are only two things in Computer Sciences: cache invalidation and naming things.

—— Phil Karlton

誠如上述所言,編程中變量命名確實(shí)令人很頭疼。我們模糊地知道,Vue 組件的名稱最好不要和原生 HTML 標(biāo)簽相同。為了避免重名,通常會(huì)在組件名稱前面加上一個(gè)前綴,如 el-button、el-input、el-date-picker。這通常不會(huì)有什么問題,但有時(shí)候你的模板中混雜了原生 HTML 標(biāo)簽和組件標(biāo)簽,要想?yún)^(qū)分它們并不是很容易。

當(dāng)我看到 Ant.design 的 React 組件是下面這樣的時(shí)候,我感覺到一種自由的味道。首先,組件名可以使用原生 HTML 標(biāo)簽名,意味著再也不用較勁腦汁去規(guī)避原生 HTML 標(biāo)簽了。另外,這些組件都使用了首字母大寫標(biāo)簽名,使它們很容易地與原生小寫的 HTML 標(biāo)簽區(qū)分。

ReactDOM.render(
 <div>
  <Button type="primary">Primary</Button>
  <Input placeholder="Basic usage" />
  <Select defaultValue=".com" style={{ width: 70 }}>
   <Option value=".com">.com</Option>
   <Option value=".jp">.jp</Option>
   <Option value=".cn">.cn</Option>
   <Option value=".org">.org</Option>
  </Select>
 </div>,
 mountNode
);

受 Ant.design 的啟發(fā),我思考 Vue 組件命名能不能達(dá)到同樣的效果呢?要找到答案,必須摸清楚 Vue 組件命名到底有什么限制。下面將分別從 Vue 1.0 和 Vue 2.0 來談?wù)劷M件命名的機(jī)制:

Vue 1.0 組件命名機(jī)制

組件注冊(cè)

我們以一個(gè)最簡單的例子來研究 Vue 組件的注冊(cè)過程:

Vue.component('MyComponent', {
 template: '<div>hello, world</div>'
})

通過跟蹤代碼的執(zhí)行過程,發(fā)現(xiàn)對(duì)組件的名稱有兩處檢查。

檢查名稱是否與 HTML 元素或者 Vue 保留標(biāo)簽重名,不區(qū)分大小寫。可以發(fā)現(xiàn),只檢查了常用的 HTML 元素,還有很多元素沒有檢查,例如 button、main。

if (type === 'component' && (commonTagRE.test(id) || reservedTagRE.test(id))) {
 warn('Do not use built-in or reserved HTML elements as component ' + 'id: ' + id);
}

// var commonTagRE = /^(div|p|span|img|a|b|i|br|ul|ol|li|h1|h2|h3|h4|h5|h6|code|pre|table|th|td|tr|form|label|input|select|option|nav|article|section|header|footer)$/i;
// var reservedTagRE = /^(slot|partial|component)$/i;

檢查組件名稱是否以字母開頭,后面跟字母、數(shù)值或下劃線。

if (!/^[a-zA-Z][\w-]*$/.test(name)) {
 warn('Invalid component name: "' + name + '". Component names ' + 'can only contain alphanumeric characaters and the hyphen.');
}

基于以上兩點(diǎn),可以總結(jié)出組件的命名規(guī)則為:組件名以字母開頭,后面跟字母、數(shù)值或下劃線,并且不與 HTML 元素或 Vue 保留標(biāo)簽重名。

然而我們注意到,在上面的檢查中,不符合規(guī)則的組件名稱是 warn 而不是 error,意味著檢查并不是強(qiáng)制的。實(shí)際上,Vue 組件注冊(cè)的名稱是沒有限制的。你可以用任何 JavaScript 能夠表示的字符串,不管是數(shù)字、特殊符號(hào)、甚至漢字,都可以成功注冊(cè)。

模板解析

雖然 Vue 組件沒有命名限制,但是我們終究是要在模板中引用的,不合理的組件名可能會(huì)導(dǎo)致我們無法引用它。

為了弄清楚 Vue 是如何將模板中的標(biāo)簽對(duì)應(yīng)到自定義組件的,我們以一段簡單的代碼說明:

new Vue({
 el: '#app',
 template: '<my-component></my-component>'
})

總體來說,模板解析分為兩個(gè)過程:

首先,Vue 會(huì)將 template 中的內(nèi)容插到 DOM 中,以方便解析標(biāo)簽。由于 HTML 標(biāo)簽不區(qū)分大小寫,所以在生成的標(biāo)簽名都會(huì)轉(zhuǎn)換為小寫。例如,當(dāng)你的 template 為 <MyComponent></MyComponent> 時(shí),插入 DOM 后會(huì)被轉(zhuǎn)換為 <mycomponent></mycomponent>。

然后,通過標(biāo)簽名尋找對(duì)應(yīng)的自定義組件。**匹配的優(yōu)先順序從高到低為:原標(biāo)簽名、camelCase化的標(biāo)簽名、PascalCase化的標(biāo)簽名。**例如 <my-component> 會(huì)依次匹配 my-component、myComponent、MyComponent。camelCase 和 PascalCase 的代碼如下:

var camelizeRE = /-(\w)/g;

function camelize(str) {
 return str.replace(camelizeRE, toUpper);
}

function toUpper(_, c) {
 return c ? c.toUpperCase() : '';
}

function pascalize(str) {
 var camelCase = camelize(str);
 return camelCase.charAt(0).toUpperCase() + camelCase.slice(1)
}

對(duì)于一個(gè) Vue 新手,經(jīng)常對(duì)以下示例代碼不能正常運(yùn)行感到非常疑惑:

Vue.component('MyComponent', {
 template: '<div>hello, world</div>'
})

new Vue({
 el: '#app',
 template: '<MyComponent></MyComponent>'
})

如果我們按照模板解析的過程推理,就很好解釋了。模板 <MyComponent></MyComponent> 插入到 DOM 后會(huì)變成 <mycomponent></mycomponent>。標(biāo)簽 mycomponent 匹配的組件依次為 mycomponent(原標(biāo)簽名)、mycomponent(camelCase形式)、Mycomponent(PascalCase形式),并沒有匹配到注冊(cè)的組件名 MyComponent,所以會(huì)報(bào)找不到組件 <mycomponent> 的警告。

命名限制

通過分析組件注冊(cè)和模板解析的過程,發(fā)現(xiàn) Vue 組件命名限制并沒有我們想象得多。大家可以嘗試一下各種命名,我試過 <a_=-*%按鈕></a_=-*%按鈕> 都可正常運(yùn)行。

但是,并不意味著完全沒有限制。由于在模板需要插入到 DOM 中,所以模板中的標(biāo)簽名必須能夠被 DOM 正確地解析。主要有三種情況:一是完全不合法的標(biāo)簽名,例如 </>;二是與 HTML 元素重名會(huì)產(chǎn)生不確定的行為,例如使用 input 做組件名不會(huì)解析到自定義組件,使用 button 在 Chrome 上正常但在 IE 上不正常;三是與 Vue 保留的 slot、partial、component 重名,因?yàn)闀?huì)優(yōu)先以本身的意義解析,從而產(chǎn)生非預(yù)期的結(jié)果。

上述命名限制存在的根本原因,在于模板解析的過程依賴了 DOM。能不能對(duì)模板解析過程改進(jìn)一下,使其不依賴于 DOM 呢?實(shí)際上,這正是 Vue 2.0 的主要改進(jìn),將模板解析過程使用 Virtual DOM 實(shí)現(xiàn),使得組件命名更加靈活。

Vue 2.0 組件命名機(jī)制

組件注冊(cè)

Vue 2.0 的組件注冊(cè)過程與 Vue 1.0 基本相同,只是 HTML 標(biāo)簽和 Vue 保留標(biāo)簽范圍有些不同:

// 區(qū)分大小寫
var isHTMLTag = makeMap(
 'html,body,base,head,link,meta,style,title,' +
 'address,article,aside,footer,header,h1,h2,h3,h4,h5,h6,hgroup,nav,section,' +
 'div,dd,dl,dt,figcaption,figure,hr,img,li,main,ol,p,pre,ul,' +
 'a,b,abbr,bdi,bdo,br,cite,code,data,dfn,em,i,kbd,mark,q,rp,rt,rtc,ruby,' +
 's,samp,small,span,strong,sub,sup,time,u,var,wbr,area,audio,map,track,video,' +
 'embed,object,param,source,canvas,script,noscript,del,ins,' +
 'caption,col,colgroup,table,thead,tbody,td,th,tr,' +
 'button,datalist,fieldset,form,input,label,legend,meter,optgroup,option,' +
 'output,progress,select,textarea,' +
 'details,dialog,menu,menuitem,summary,' +
 'content,element,shadow,template'
);

// 不區(qū)分大小寫
var isSVG = makeMap(
 'svg,animate,circle,clippath,cursor,defs,desc,ellipse,filter,font,' +
 'font-face,g,glyph,image,line,marker,mask,missing-glyph,path,pattern,' +
 'polygon,polyline,rect,switch,symbol,text,textpath,tspan,use,view',
 true
);

var isReservedTag = function (tag) {
 return isHTMLTag(tag) || isSVG(tag)
};

// 區(qū)分大小寫
var isBuiltInTag = makeMap('slot,component', true);

雖然 HTML 元素重名警告的標(biāo)簽數(shù)大大增加了,但重要的是重名區(qū)分大小寫,所以我們可以愉快地使用 Input、Select、Option 等而不用擔(dān)心重名。這個(gè)功勞屬于 Vue 2.0 引入的 Virtual DOM。

模板解析

前面提到,Vue 2.0 相對(duì)于 1.0 的最大改進(jìn)就是引入了 Virtual DOM,使模板的解析不依賴于 DOM。

使用 Virtual DOM 解析模板時(shí),不必像 DOM 方式那樣將模板中的標(biāo)簽名轉(zhuǎn)成小寫,而是原汁原味地保留原始標(biāo)簽名。然后,使用原始的標(biāo)簽名進(jìn)行匹配組件。例如,<MyComponent></MyComponent> 不會(huì)轉(zhuǎn)為為小寫形式,直接以 MyComponent 為基礎(chǔ)開始匹配。當(dāng)然,匹配的規(guī)則與 1.0 是一樣的,即依次匹配:原標(biāo)簽名、camelCase化的標(biāo)簽名、PascalCase化的標(biāo)簽名。

之前在 1.0 不能正常運(yùn)行的示例代碼,在 2.0 中可以正常運(yùn)行了:

Vue.component('MyComponent', {
 template: '<div>hello, world</div>'
})

new Vue({
 el: '#app',
 template: '<MyComponent></MyComponent>'
})

在 Vue 1.0 和 2.0 中還有一種定義組件模板的方式,即使用 DOM 元素。在這種情況下,解析模板時(shí)仍然會(huì)將標(biāo)簽轉(zhuǎn)為小寫形式。所以下面的代碼,在 1.0 和 2.0 均不能正常運(yùn)行。

// index.html
<div id="app">
 <MyComponent></MyComponent>
</div>

// main.js
Vue.component('MyComponent', {
 template: '<div>hello, world</div>'
})

new Vue({
 el: '#app'
})

命名限制

Vue 2.0 中組件的命名限制與 1.0 的最大區(qū)別在于區(qū)分了大小寫??偨Y(jié)一下就是:一是不使用非法的標(biāo)簽字符;二是不與 HTML 元素(區(qū)分大小寫)或 SVG 元素(不區(qū)分大小寫)重名;三是不使用 Vue 保留的 slot 和 component(區(qū)分大小寫)。

除了以上三條,由于 Vue 2.0 內(nèi)置了 KeepAlive、Transition、TransitionGroup 三個(gè)組件,所以盡量避免與這三個(gè)組件重名。但從另一方面講,你也可以故意重名來實(shí)現(xiàn)一些特殊的功能。例如,keep-alive 的匹配順序?yàn)?keep-alive、keepAlive、KeepAlive,所以我們可以注冊(cè)一個(gè) keep-alive 組件來攔截 KeepAlive 匹配。

總結(jié)

到這里,我們可以知道 Vue 2.0 完全可以像 React 那樣使用 PascalCase 形式的組件標(biāo)簽。對(duì)于 Vue 1.0,想以 PascalCase 形態(tài)寫模板,盡量以全小寫或者僅首字母大寫形式注冊(cè)組件,例如 <InputNumber> 組件,可以注冊(cè)為 inputnumber 或者 Inputnumber。但是,如果你想在 1.0 中使用 Input、Select 這類與 HTML 元素重名的標(biāo)簽名,基本上是無解的,所以是時(shí)候嘗試下 Vue 2.0 了。

以上就是本文的全部內(nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • 解決vue中使用swiper 插件出錯(cuò)的問題

    解決vue中使用swiper 插件出錯(cuò)的問題

    這篇文章主要介紹了vue中使用swiper 插件出錯(cuò)問題及解決辦法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-08-08
  • Vue實(shí)現(xiàn)可移動(dòng)水平時(shí)間軸

    Vue實(shí)現(xiàn)可移動(dòng)水平時(shí)間軸

    這篇文章主要為大家詳細(xì)介紹了Vue實(shí)現(xiàn)可移動(dòng)水平時(shí)間軸,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2020-06-06
  • vue-cli3設(shè)置代理無效的解決

    vue-cli3設(shè)置代理無效的解決

    這篇文章主要介紹了vue-cli3設(shè)置代理無效的解決方案,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-07-07
  • vue與iframe之間的信息交互的實(shí)現(xiàn)

    vue與iframe之間的信息交互的實(shí)現(xiàn)

    這篇文章主要介紹了vue與iframe之間的信息交互的實(shí)現(xiàn),文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧
    2020-04-04
  • antd-DatePicker組件獲取時(shí)間值,及相關(guān)設(shè)置方式

    antd-DatePicker組件獲取時(shí)間值,及相關(guān)設(shè)置方式

    這篇文章主要介紹了antd-DatePicker組件獲取時(shí)間值,及相關(guān)設(shè)置方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2020-10-10
  • 詳解vue-router導(dǎo)航守衛(wèi)

    詳解vue-router導(dǎo)航守衛(wèi)

    今天小編就為大家分享一篇關(guān)于詳解vue-router導(dǎo)航守衛(wèi),小編覺得內(nèi)容挺不錯(cuò)的,現(xiàn)在分享給大家,具有很好的參考價(jià)值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • Vue2+JS實(shí)現(xiàn)掃雷小游戲

    Vue2+JS實(shí)現(xiàn)掃雷小游戲

    實(shí)現(xiàn)小游戲可以鍛煉自己的邏輯思維能力,也不會(huì)很枯燥,完成時(shí)會(huì)給自己帶來一種滿足感。本文就將利用Vue和JS實(shí)現(xiàn)簡單的掃雷小游戲,需要的可以參考一下
    2022-06-06
  • axios中post請(qǐng)求json和application/x-www-form-urlencoded詳解

    axios中post請(qǐng)求json和application/x-www-form-urlencoded詳解

    Axios是專注于網(wǎng)絡(luò)數(shù)據(jù)請(qǐng)求的庫,相比于原生的XMLHttpRequest對(duì)象,axios簡單易用,下面這篇文章主要給大家介紹了關(guān)于axios中post請(qǐng)求json和application/x-www-form-urlencoded的相關(guān)資料,需要的朋友可以參考下
    2022-10-10
  • vue使用rules實(shí)現(xiàn)表單字段驗(yàn)證

    vue使用rules實(shí)現(xiàn)表單字段驗(yàn)證

    這篇文章主要為大家詳細(xì)介紹了vue使用rules實(shí)現(xiàn)表單字段驗(yàn)證,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-08-08
  • vue項(xiàng)目中引入noVNC遠(yuǎn)程桌面的方法

    vue項(xiàng)目中引入noVNC遠(yuǎn)程桌面的方法

    下面小編就為大家分享一篇vue項(xiàng)目中引入noVNC遠(yuǎn)程桌面的方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧
    2018-03-03

最新評(píng)論

钟山县| 房山区| 明溪县| 株洲县| 大方县| 通江县| 绥化市| 库车县| 苍梧县| 三亚市| 南涧| 湖北省| 深泽县| 鱼台县| 浙江省| 乾安县| 海丰县| 肥城市| 曲阜市| 曲麻莱县| 江西省| 岳池县| 崇左市| 大理市| 治多县| 永登县| 晋城| 尤溪县| 南雄市| 响水县| 承德县| 昌宁县| 雷波县| 长治市| 郸城县| 偏关县| 石首市| 中西区| 龙山县| 宜川县| 伊川县|