[Bem] 前端命名规范

avatarplhDigital nomad
一直很困惑,一个class类名该怎么命名才能有规范.事实上,这中前端命名规范不仅仅是多人协作方式问题,如果看到乱的命名规范,甚至无法自己和自己相处.事实上,webapp越写到后面,越加渴望规范...

code 示例,,,,名约定的模式如下:

.block{}
.block__element{}
.block--modifier{}

什么是BEM

  • B(block-块)
    代表了更高级别的抽象或组件
  • E(element-元素)
    block元素的后代
  • M(Modifier-修饰符) block元素的不同版本.不同状态

前端规范

相当重要的东西,首先从命名规则做起....所以,BEM(或BEM的变体)是一个非常有用,强大,简单的命名约定,以至于让你的前端代码更容易阅读和理解,更容易协作,更容易控制,更加健壮和明确而且更加严密。

Block

从block说起吧,block被用来描述它的目的,它是什么?菜单栏或者按钮,,,而不是它的状态,红色或者大. 举个例子

<!-- 正确的命名方式,error看起来是充满语义化的. -->
<div class="error"></div>

<!-- 不对. 这是外观的描述 -->
<div class="red-text"></div>

block使用指南

<!-- `header` block -->
<header class="header">
    <!-- Nested `logo` block -->
    <div class="logo"></div>

    <!-- Nested `search-form` block -->
    <form class="search-form"></form>
</header>

Element - 元素

主要用来描述状态,例如这是什么,, item/text等, 而不是它的状态, (什么类型,看起来像什么,red/big) 完整的看起来应该是block-name__element-name

Element - 元素 实践

<!-- `search-form` block -->
<form class="search-form">
    <!-- `input` element in the `search-form` block -->
    <input class="search-form__input">

    <!-- `button` element in the `search-form` block -->
    <button class="search-form__button">Search</button>
</form>

modifier - 描述

主要用于状态描述 - 例如 big/red

最佳实践

有利于大型项目开发吧.开发方式之所以能流传开来,就说明它是有一定的实践价值的 我个人认为他还是提出了模块与模块,组件与组件,模块与组件之间的管理方式。如何通过一种命名方式更好的管理和维护他们。

Element-UI 一段代码

<label
    class="el-checkbox-button"    // 描述block-name 块名
      :class="[
        size ? 'el-checkbox-button--' + size : '',    // el-checkbox-button--size
        { 'is-disabled': isDisabled },
        { 'is-checked': isChecked },
        { 'is-focus': focus },
      ]"
    role="checkbox"
    :aria-checked="isChecked"
    :aria-disabled="isDisabled"
    >
    <input
      v-if="trueLabel || falseLabel"
      class="el-checkbox-button__original"
      type="checkbox"
      :name="name"
      :disabled="isDisabled"
      :true-value="trueLabel"
      :false-value="falseLabel"
      v-model="model"
      @change="handleChange"
      @focus="focus = true"
      @blur="focus = false">
    <input
      v-else
      class="el-checkbox-button__original"   //  block-name__类型
      type="checkbox"
      :name="name"
      :disabled="isDisabled"
      :value="label"
      v-model="model"
      @change="handleChange"
      @focus="focus = true"
      @blur="focus = false">
    <span class="el-checkbox-button__inner"   // block-name__element-name
      v-if="$slots.default || label"
      :style="isChecked ? activeStyle : null">
      <slot>{{label}}</slot>
    </span>
  </label>

关于modifier的更多实践

<div
    :class="[
      'el-color-picker',
      disabled ? 'is-disabled' : '',
      colorDisabled ? 'is-disabled' : '',
      colorSize ? `el-color-picker--${ colorSize }` : ''   // 事实上 modifier往往是这样子用的.
    ]"
    v-clickoutside="hide" />

Reference

BEM 大漠的博客