原文:https://github.com/kuitos/kuitos.github.io/issues/30
更多精彩文章:https://github.com/kuitos/kuitos.github.io/issues/css
Block Element Modifier is a methodology, that helps you to achieve reusable components and code sharing in the front-endhtml
原義:一個css編寫規範git
**B(block): 獨立的頁面及邏輯單元,咱們一般意義上的component
E(element): 塊中的組成部分,不能脫離塊單獨存在
M(modifier): 修飾符,可修飾塊或元素** github
它提出來一種命名規範:web
block__element--modifier
example:app
<div class="header header--blink"> <div class="header__title header__title--red-border">title</div> </div>
這段html表達的意思是:一個header組件(block),其中包括了一個title元素(element),同時header塊具有閃爍(blink)特性,title元素具有紅邊框特性。ide
BEM的這種命名方式看似美妙,但實則是與標準相悖的解決方案(後面講)。因此我不會推薦這種css規範,我想說的是從BEM這種思路,咱們能夠將它做爲咱們組件粒度劃分的方法論。ui
從BEM劃分策略看頁面:
spa
Block是一個完整獨立的邏輯單元,是一個概念完備的組件,它包含完整的邏輯單元(js),模版(template)及樣式(css)設計
Element是Block的組成部分,Block是它的宿主,Element沒法脫離宿主存在
Modifier是塊/元素的修飾符
以一個tab列表組件爲例:
咱們的目錄結構應該這樣去組織
代碼可能這樣去寫
// tabset app.directive('tabset', function(){ return { restrict:'E', templateUrl:'tab-set.html', scope:{ tabs:'=' } }; });
<!-- tab-set.html --> <div ng-repeat="tab in tabs track by $index"> <tab info="tab"></tab> </div> <div class="tab-border"></div>
// tab app.directive('tab', function(){ return { restrict:'E', require:'^tabset', templateUrl:'tab.html', scope:{ tab:'=info' } }; });
<!-- tab.html --> <div> <span ng-bind="tab.title"></span> </div>
調用時這麼去用
<tabset tabs="tabs"></tabset>
app.controller('ctrl', ctrl); ctrl.$inject = ['$scope']; function ctrl($scope){ $scope.tabs = [{title:'tab1'}, {title:'tab2'}]; }
Tab組件做爲TabSet的一部分是沒辦法獨立存在的,它必須依託於TabSet纔有意義。
對調用者而言,暴露給它的是TabSet組件,TabSet纔是一個Block(組件),Tab是一個Element。
在components這一層,咱們能看到的都是一個個完整的Block,並且每一個Block都是獨立存在不會互相依賴的平級關係。
總結來說就是
若是你在components層級發現了存在相互依賴的兩個組件,趕忙從新想一想你的組件規劃是否是有問題
咱們能夠將 ‘組件之間的關係是組合而不是依賴’ 做爲咱們開發設計組件的guideline,基於此,咱們須要確立的思想就是,在現現在的web開發模式下,咱們更應該採用 面向組件(COP) 的方式開發組件而不是之前流行的 面向對象(OOP) 的方式(以ExtJs爲表明),組件之間更多的是組合關係,繼承的場景在組件開發領域不多並且大多時候能夠用其餘方式實現(組合或者修飾符的方式)。
拓展章節:
[web語義化標準解讀]()