@CSS 方法论 --- BEM思想

796 阅读2分钟

BEM 思想

其实 BEM 思想就是对整个 html 固件的描述,我们构建一个合理的骨架,编写css有样式的时候,会显得更加的合理有层次和结构性,BEM 思想特别适合制作 UI 框架,框架一般都是结构性很强。

在计算机科学领域,只有2个非常难解决的问题:一个是缓存失效,而另一个则是命名。-Phil Karlton

这里我们参考 vantui 微信小程序ui框架来分析,bem 思想是如何贯穿到我们的ui框架里面的

有点

具有可维护性,思想结构统一,容易看懂

理解BEM

B - block E - Element M - Modifier

BEM 的命令分割方式

  • __ 双下划线,是 block 和 element
  • -- 双中划线,是 elment 和 modifier 的分割线
  • - 中短横线,是 modifier 的细节

几种使用方式

  • .block--mod

  • .block__elem--mod

  • .block--color-black

  • .block--color-red

分析有赞的 vanweapp 的bem的实现

首先有 wxs 脚本,为了能在 wxml 文件里面使用

var PREFIX = 'van-'

/*
    * @params {name} string bem block
    * @params {mods} array bem mods
*/
function join(name, mods) {
    name = PREFIX + name;
    mods = mods.map((mod) => {
        return name + '--' + mod
    })
    mods.unshift(name)
    return mods.join(' ')
}

/*
    * traversing 函数式一个 mods 的调度器函数,通过他来处理 mod 分部
    * @params {mods} array bem mods
    * @params {conf} mods ,conf 不同的数据类型有不同的处理方式
*/
function traversing(mods, conf) {
  if (!conf) {
    return;
  }

  if (typeof conf === 'string' || typeof conf === 'number') {
    mods.push(conf);
  } else if (array.isArray(conf)) {
    conf.forEach(function(item) {
      traversing(mods, item);
    });
  } else if (typeof conf === 'object') {
    object.keys(conf).forEach(function(key) {
      conf[key] && mods.push(key);
    });
  }
}


/*
    * @params {name} string bem name
    * @params {conf} mods ,conf 不同的数据类型有不同的处理方式
*/
function bem(name, conf) {
  var mods = [];
  traversing(mods, conf);
  return join(name, mods);
}

module.exports.bem = bem

在 vanweapp 中为了性能的 bem 被调用了之后,还会缓存起来,以后遇到相同的值的时候,直接使用缓存里面的内容

来看一个实例

<!--// nav-bar 组件-->
<wxs src=".../wxs/utils.wxs" module="utils"></wxs>

<view
  class="{{ utils.bem('nav-bar', { fixed: 'fixed' }) }} custom-class {{ border ? 'van-hairline--bottom' : '' }}"
  style="z-index: {{ zIndex }}; {{ safeAreaInsetTop ? 'padding-top: ' + statusBarHeight + 'px;' : '' }}"
>
</view>
<!--notice-bar 组件-->
<wxs src="../wxs/utils.wxs" module="utils" />

<view
  wx:if="{{ show }}"
  class="custom-class {{ utils.bem('notice-bar', { withicon: mode, wrapable }) }}"
  style="color: {{ color }}; background-color: {{ backgroundColor }};"
  bind:tap="onClick"
>

我初步得知 bem 函数,一般都是用在组价的最层,表示一些行为。