前端组件化开发时组件className命名规范

4,170 阅读5分钟

前言

    前端开发无论web还是h5都会涉及各种规范,脚手架使用规范、目录规范、命名规范、文档规范、流程规范等等,本文主要针对前端命名规范中dom元素类名(className)的命名规范提出个人的一些想法,希望能给读者带来帮助或启发。

主流命名规范

1. OOCSS

Object-Oriented CSS,示例:

<div class="sizeOne bgBlue solidGray"></div>

.sizeOne {width: 25%;}
.bgBlue {background:blue;}
.solidGray {border: 1px solid #ccc;}

oocss的核心原则:

  1. 独立的结构和样式
  2. 独立的容器和内容

其优点:

  • 减少CSS代码
  • 具有清洁的HTML标记,有语义的类名,逻辑性强的层次关系
  • 语义标记,有助于SEO
  • 更好的页面优化,更快的加载时间(因为有很多组件重用)
  • 可扩展的标记和CSS样式,有更多的组件可以放到库中,而不影响其他的组件
  • 能轻松构造新的页面布局,或制作新的页面风格

其缺陷:

  • OOCSS适合真正的大型网站开发,因为大型网站用到的可重用性组件特别的多,如果运用在小型项目中可能见不到什么成效。所以用不用OOCSS应该根据你的项目来决定。
  • 如果没用巧妙的使用,创建组件可能对于你来说是一堆没用的东西,成为一烂摊子,给你的维护带来意想不到的杯具,说不定还是个维护的噩梦。
  • 最好给每一个组件备写一份说明文档,有助于调用与维护
    参考链接:www.w3cplus.com/css/oocss-c…

2. SMACSS

参考链接:medium.com/@savemuse/s…

3. SUITCSS

参考链接:w3ctech.com/topic/1939

4. Atomic

参考链接:www.geeksforgeeks.org/introductio…

5. BEM

参考链接:getbem.com/introductio…

Block、Element、Modifier,BEM是我目前在使用的命名方式,也是本文重点要讲述的,基于BEM的规范制定了一套符合业务、框架以及开发模式的规范。首先简单介绍下BEM,详细内容可查看参考链接。

Block

独立的有意义的实体,eg:

headercontainermenucheckboxinputfooter等,它是在整个页面布局时,划分的单独模块。

Element

元素,是Block下的子元素,其没有独立的意义,但属于Block的一部分,eg:

menu itemlist itemcheckbox captionheader title

Modifier

Block或Element上的标志标识,用来改变外观、状态、行为、标记等,eg:

disabled、 highlightedcheckedfixedsize bigcolor yellow

我的命名规范

基于BEM,我进行了扩展,我认为项目名也可以是一个Block,而项目旗下的页面,组件都可以视为block下的元素element,项目是独立的实体,组件、页面是其的一部分,page、component等是他的标识modifier,该概念完全符合BEM的设计理念,也比较适用于我们项目开发。

在我们使用vue、react或者angular开发业务时,势必会涉及到这几个概念:

  1. 页面级组件;
  2. 全局通用组件;
  3. 模块内通用组件;
  4. 页面独有的组件;

针对这些场景,我们如何命名区分,达到通过类名就能大致了解组件的用途,甚至自注释,同时也能有效的防止命名重复导致的样式冲突呢?

1. 页面级组件

路由所对应的页面,也称为页面级组件。

<页面>--page 必要时候 可以带上项目缩写:<项目缩写>__<页面>--page
eg:
外层页面目录:my-order;
页面:我的订单;
命名:my-orders--page;

2. 全局通用组件

全局通用的组件,适用于不同模块下的多个页面。

<组件名>--global-component
必要时,为了防止命名冲突可以带上项目简写:
<项目缩写>__<组件名>--global-component
eg:
全局组件存放路径:src/components
通用组件:按钮组件
命名:button--global-component

3. 模块内通用组件

模块内多个页面都要用到的组件,我将它称之为模块内通用组件,通常存放在一级路由文件夹下的components下,例如/src/pages/personal-center/components。

<组件名>--module-component
必要时,为了防止命名冲突可以带上项目简写:<项目缩写>__<组件名>--module-component
eg:
存放路径:/src/pages/personal-center/components
模块内通用组件:弹窗组件
命名:modal--module-component

4. 页面独有组件

仅适用于当前页面的组件,我将它称之为页面独有组件。

<组件名>--component

eg:
存放路径:/src/pages/personal-center/my-order/components模块内通用组件:标签组件
命名:tag--component

modifier新增四种:page、global-component、module-component、component。

组件名、模块名、页面名称都使用 ‘-’ 连接,eg:record-item、award-detail。

以上的命名都是针对组件容器的class命名,那么组件内部的子元素该如何命名呢?

1. 统一前缀命名

所有子元素都使用统一的前缀去命名,eg:button__text。

该方法的缺点,如果组件名称长,看着不优雅,很多重复,若使用变量定义,eg:

const classPrefix = 'tpc_datetime-picker'

<div className={`${classPrefix}__title`} />

这么写的话,总感觉也不是特别优雅,但也还在接受范围。

2. 使用组件名前缀

使用组件名称,去除项目简写,eg:button--disabled

针对子元素内部的命名,eg:button__label--warning

在组件开发过程中,建议可以将前缀使用变量保存,css也是。如此去命名你的class,既明了,又能防止命名重复导致样式冲突,让每一个类变得更有意义。可能有的前端比较反感命名长,喜欢用简短的命名,可以适当调整类名的前缀,让class不显得过长,如此命名,防重复,类名可读性很高,会让你的业务更清晰,html的结构层次也更明了。