組件設計之BEM法則

組件設計之BEM法則

原文:https://github.com/kuitos/kuitos.github.io/issues/30
更多精彩文章:https://github.com/kuitos/kuitos.github.io/issues/css

BEM定義

Block Element Modifier is a methodology, that helps you to achieve reusable components and code sharing in the front-endhtml

BEM概念

原義:一個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劃分策略看頁面:
aspa

  1. Block是一個完整獨立的邏輯單元,是一個概念完備的組件,它包含完整的邏輯單元(js),模版(template)及樣式(css)設計

  2. Element是Block的組成部分,Block是它的宿主,Element沒法脫離宿主存在

  3. 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爲表明),組件之間更多的是組合關係,繼承的場景在組件開發領域不多並且大多時候能夠用其餘方式實現(組合或者修飾符的方式)。

拓展章節:

  1. [web語義化標準解讀]()

相關文章
相關標籤/搜索