Vue 元件命名,CSS的標準文件流

shkstart發表於2022-01-13

1、檢查名稱是否與 HTML 元素或者  Vue 保留標籤重名,不區分大小寫。可以發現,只檢查了常用的 HTML 元素,還有很多元素沒有檢查,例如 button、main。


if (type === 'component' && (commonTagRE.test(id) || reservedTagRE.test(id))) {undefined

  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;

2、檢查元件名稱是否以字母開頭,後面跟字母、數值或下劃線。


if (!/^[a-zA-Z][\w-]*$/.test(name)) {undefined

  warn('Invalid component name: "' + name + '". Component names ' + 'can only   contain alphanumeric characaters and the hyphen.');

}

基於以上兩點,可以總結出元件的命名規則為:元件名以字母開頭,後面跟字母、數值或下劃線,並且不與 HTML 元素或 Vue 保留標籤重名。

然而我們注意到,在上面的檢查中,不符合規則的元件名稱是 warn 而不是 error,意味著檢查並不是強制的。實際上,Vue 元件註冊的名稱是沒有限制的 。你可以用任何 JavaScript 能夠表示的字串,不管是數字、特殊符號、甚至漢字,都可以成功註冊。

模板解析

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

為了弄清楚 Vue 是如何將模板中的標籤對應到自定義元件的,我們以一段簡單的程式碼說明:


new Vue({undefined

  el: '#app',

  template: '<my-component></my-component>'

})

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

首先,Vue 會將 template 中的內容插到 DOM 中,以方便解析標籤。由於 HTML 標籤不區分大小寫,所以在生成的標籤名都會轉換為小寫。例如,當你的 template 為 <MyComponent></MyComponent> 時,插入 DOM 後會被轉換為 <mycomponent></mycomponent>。(注意:我們現在討論的是 vue 1.x 下的情景)

然後,透過標籤名尋找對應的自定義元件。匹配的優先順序從高到低為:原標籤名、camelCase化的標籤名、PascalCase化的標籤名。例如 <my-component> 會依次匹配 my-component、myComponent、MyComponent。 前端培訓

camelCase 和 PascalCase 是如何實現的程式碼如下:


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

function camelize(str) {undefined

  return str.replace(camelizeRE, toUpper);

}

function toUpper(_, c) {undefined

  return c ? c.toUpperCase() : '';

}

function pascalize(str) {undefined

  var camelCase = camelize(str);

  return camelCase.charAt(0).toUpperCase() + camelCase.slice(1)

}

對於與一個 Vue 新手,經常對以下示例程式碼不能正常執行感到非常疑惑:(注意:我們現在討論的是 vue 1.x 下的情景)


Vue.component('MyComponent', {undefined

  template: '<div>hello, world</div>'

})

new Vue({undefined

  el: '#app',

  template: '<MyComponent></MyComponent>'

})

如果我們按照模板解析的過程推理,就很好解釋了。模板 <MyComponent></MyComponent> 插入到 DOM 後會變成 <mycomponent></mycomponent>。標籤 mycomponent 匹配的元件依次為 mycomponent(原標籤名)、mycomponent(camelCase形式)、Mycomponent(PascalCase形式),並沒有匹配到註冊的元件名 MyComponent,所以會報找不到元件 的警告。

命名限制

透過分析元件註冊和模板解析的過程,發現 Vue 元件命名限制並沒有我們想象得多。大家可以嘗試一下各種命名,我試過 <a_=-*%按鈕></a_=-*%按鈕> 都可正常執行。

但是,並不意味著完全沒有限制。由於在模板需要插入到 DOM 中,所以模板中的標籤名必須能夠被 DOM 正確地解析。

主要有三種情況:

一是完全不合法的標籤名,例如 </>;

二是與 HTML 元素重名會產生不確定的行為,例如使用 input 做元件名不會解析到自定義元件,使用 button 在 Chrome 上正常但在 IE 上不正常;

三是與 Vue 保留的 slot、partial、component 重名,因為會優先以本身的意義解析,從而產生非預期的結果。

上述命名限制存在的根本原因,在於模板解析的過程依賴了 DOM。能不能對模板解析過程改進一下,使其不依賴於 DOM 呢?實際上,這正是 Vue 2.0 的主要改進,將模板解析過程使用 Virtual DOM 實現,使得元件命名更加靈活。

Vue 2.x 元件命名機制

==============

元件註冊

Vue 2.0 的元件註冊過程與 Vue 1.0 基本相同,只是 HTML 標籤和 Vue 保留標籤範圍有些不同:


// 區分大小寫

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'

);

// 不區分大小寫

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) {undefined

  return isHTMLTag(tag) || isSVG(tag)

};

// 區分大小寫

var isBuiltInTag = makeMap('slot,component', true);

雖然 HTML 元素重名警告的標籤數大大增加了,但重要的是重名區分大小寫,所以我們可以愉快地使用 Input、Select、Option 等而不用擔心重名。這個功勞屬於 Vue 2.0 引入的 Virtual DOM。

(關於 vue 2.0 中的新特性,請看:[Vue 2.0 釋出了!](

)、[Announcing Vue.js 2.0](

))

模板解析

前面提到,Vue 2.0 相對於 1.0 的最大改進就是引入了 Virtual DOM,使模板的解析不依賴於 DOM。

使用 Virtual DOM 解析模板時,不必像 DOM 方式那樣將模板中的標籤名轉成小寫,而是原汁原味地保留原始標籤名。然後,使用原始的標籤名進行匹配元件。例如,<MyComponent></MyComponent> 不會轉為為小寫形式,直接以 MyComponent 為基礎開始匹配。當然,匹配的規則與 1.0 是一樣的,即依次匹配:原標籤名、camelCase化的標籤名、PascalCase化的標籤名。

之前在 1.0 不能正常執行的示例程式碼,在 2.0 中可以正常執行了:


Vue.component('MyComponent', {undefined

  template: '<div>hello, world</div>'

})

new Vue({undefined

  el: '#app',

  template: '<MyComponent></MyComponent>'

})
在 Vue 1.0 和 2.0 中還有一種定義元件模板的方式,即使用 DOM 元素。在這種情況下,解析模板時仍然會將標籤轉為小寫形式。所以下面的程式碼,在 1.0 和 2.0 均不能正常執行。

版權宣告:本文為原創文章,轉載請附上原文出處連結及本宣告。下載相關影片學習資料到尚矽谷官方網站。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/27721058/viewspace-2852044/,如需轉載,請註明出處,否則將追究法律責任。

相關文章