關鍵概念
<h2 id="block">模塊</h2>
一個在邏輯和功能上獨立的頁面組件讥巡,與 Web 組件中的組件概念是等同的个初。一個模塊封裝了行為(JavaScript)办陷,模板职烧,樣式(CSS),和其他技術實現停局。模塊是獨立的,允許我們重用纸淮,從而更好地促進項目的開發(fā)。
模塊的特征
嵌套結構
模塊可以被其他的模塊嵌套在內部亚享。
??比如:一個 head
模塊可以包含一個 logo(logo
)咽块,一個搜索框(search
),和一個授權(登錄/注冊)模塊(auth
)欺税。
任意位置
模塊可以在一個頁面上使用侈沪,在多個頁面間使用揭璃,或者在多個項目間使用。模塊被實現為獨立的實體亭罪,從而使得在頁面中改變模塊的位置成為可能瘦馍,同時確保他們的功能和外觀是正常的。
因此应役,logo 和 認證表單模塊可以在不更改 CSS 和 JavaScript 代碼的情況下互相交換位置情组。
重用
一個界面可以包含多個相同模塊的實例。
<h2 id="element">元素</h2>
元素是一個模塊的組成部分箩祥,并且不可以在模塊之外使用院崇。
例如,一個菜單項不可以被單獨使用在菜單模塊的上下文之外滥比,一次它是一個元素亚脆。
<h2 id="modifier">修飾符</h2>
是否使用修飾符,是可選擇的键耕。
本質上寺滚,修飾符和 HTML 屬性是相似的。相同的模塊看起來不同屈雄,正式由于使用了修飾符村视。
例如,菜單模塊(menu
)可能會改變它自己的外觀酒奶,這取決于一個修飾符被使用在菜單模塊上蚁孔。
修飾符可以在程序運行時被改變(例如,模塊的某個 DOM 事件被觸發(fā)時)惋嚎,或者被其他模塊所改變杠氢。
<h2 id="bem-entity">BEM 實體</h2>
這個概念可以被應用在一個單獨的 BEM 實體上鼻百,也可以作為模塊,元素和修飾符的統(tǒng)稱摆尝。
<h2 id="mix">混合模式</h2>
可以將多個不同的 BEM 實體整合為一個單獨的 DOM 節(jié)點温艇。
混合模式允許我們
- 結合多個 BEM 實體的行為和風格(樣式),以及減少代碼的重復
- 在已經存在的 BEM 實體的基礎上創(chuàng)建新的新的界面組件堕汞。
讓我們考慮一個將一個模塊和另一個模塊的元素混合的案例勺爱。
讓我們假定通過一個 link
模塊來實現你項目中的鏈接。我們需要將菜單項全部用鏈接實現讯检。這有一些方式來實現我們的目的邻寿。
- 為菜單項創(chuàng)建一個可以將其轉換為鏈接的修飾符蝎土。為了實現這樣一個修飾符,必然會復制
link
模塊的行為和樣式绣否。這將會造成代碼的重復誊涯。 - 將一個通用的
link
模塊和一個 ·menu· 模塊的link
元素結合在一起。這兩個 BEM 實體的混合模式允許我們使用link
模塊的鏈接功能蒜撮,并且可以在不復制代碼的情況下使用menu
模塊額外的 CSS 規(guī)則暴构。
<h2 id="beem-tree">BEM 樹</h2>
一種使用模塊,元素和修飾符的 web 頁面結構的表示段磨。是通過 BEM 實體名稱對 DOM 樹的抽象描述取逾,包括他們的狀態(tài),順序苹支,嵌套和一些輔助性的數據砾隅。
在真實的項目中,一個 BEM 樹可以被呈現在任何支持樹結構的格式中债蜜。
讓我們來看一個 DOM 樹的例子:
<header class="header">
<img class="logo">
<form class="search-form">
<input type="input">
<button type="button"></button>
</form>
<ul class="lang-switcher">
<li class="lang-switcher__item">
<a class="lang-switcher__link" href="url">en</a>
</li>
<li class="lang-switcher__item">
<a class="lang-switcher__link" href="url">ru</a>
</li>
</ul>
</header>
相應的 BEM 樹看起來是這個樣子的
header
├──logo
└──search-form
├──input
└──button
└──lang-switcher
└──lang-switcher__item
└──lang-switcher__link
└──lang-switcher__item
└──lang-switcher__link
在 XML 和 BEMJSON格式中晴埂,相同的 BEM 樹如下:
XML
<block:header>
<block:logo/>
<block:search-form>
<block:input/>
<block:button/>
</block:search-form>
<block:lang-switcher>
<elem:item>
<elem:link/>
</elem:item>
<elem:item>
<elem:link/>
</elem:item>
</block:lang-switcher>
</block:header>
BEMJSON
{
block: 'header',
content : [
{ block : 'logo' },
{
block : 'search-form',
content : [
{ block : 'input' },
{ block : 'button' }
]
},
{
block : 'lang-switcher',
content : [
{
elem : 'item',
content : [
{ elem : 'link' }
]
},
{
elem : 'item',
content : [
{ elem : 'link' }
]
}
]
}
]
}
<h2 id="block-implementation">模塊實現</h2>
決定一個 BEM 實體包含如下一組不同的技術:
- 行為
- 外觀
- 測試
- 模板
- 文檔
- 依賴關系描述
- 輔助性數據(例如,圖片)
<h2 id="block-implementation-tec">實現技術</h2>
??用于實現一個模塊的相關技術寻定。
模塊可以使用一種或多種技術實現儒洛,比如:
- 行為 —— JavaScript,CoffeeScript
- 外觀 —— CSS,Stylus,Sass
- 模板 —— BEMHTML,BH,Pug,Handlebars,XSL
- 文檔 —— Markdown,Wiki,XML.
例如,如果一個模塊的外觀使用 CSS 定義狼速,這表明這個模塊使用 CSS 技術被實現琅锻。同樣。如果使用 Markdown 書寫一個模塊的文檔向胡,那么該模塊使用 Markdown 技術實現恼蓬。
<h2 id="block-redefinition">模塊重定義</h2>
??通過在不同的級別上添加新的功能來更改模塊的實現。
<h2 id="redefinition-level">重新定義級別</h2>
重定義級別指一組 BEM 實體和他們的部分實現僵芹。
模塊的最終實現可以被分成不同的定義級別上处硬。每一個新的級別繼承或者覆蓋之前的對模塊的實現。最終的結果是由按照連續(xù)順序的每個重定義的級別上的模塊的實現技術組裝而成的淮捆。
每一個級別上對 BEM 實體的實現技術都可以被重新定義郁油。
例如,這里有一個項目攀痊,在該項目的一個單獨的級別上使用了一個第三方庫桐腌。該第三方庫實現有現成的模塊。該具體項目的模塊被保存在另一個重定義級別上苟径。
比方說案站,我們需要修飾第三庫其中的某一個模塊的外觀。不需要在第三方庫的源碼中修改模塊的 CSS 規(guī)則棘街,或者將代碼復制到項目級別中蟆盐。我們只需要在項目級別上為模塊創(chuàng)建一些額外的 CSS 規(guī)則承边。在項目構建過程中,最終實現將會結合庫級別的原有規(guī)則和項目級別中新的樣式規(guī)則石挂。
本人才疏學淺博助,如果文中有錯誤,或者歧異痹愚,或者不恰當的地方富岳,希望大家提出來,非常愿意接受大家的批評與建議拯腮。