BEM之道:打造高效可维护的Web页面结构 —— 新手进阶+weui小程序实战

434 阅读5分钟

在前端开发领域,随着Web技术的不断演进,代码的可维护性和可读性成为了衡量项目质量的重要标准之一。良好的命名规范不仅能够提升团队协作效率,还能确保代码的长期可持续性。在众多命名规范中,BEM(Block Element Modifier)以其清晰的逻辑和高度的可扩展性脱颖而出,成为许多开发者首选的命名方法。本文将深入探讨BEM命名规范,并通过实例说明其如何帮助新手开发者高效构建页面结构,同时减少在取类名上的困扰。

BEM命名规范简介

BEM,全称为Block Element Modifier,是一种源自Yandex团队的CSS命名方法论。它通过明确界定页面中的组件、子元素以及它们的不同状态,来实现更加模块化和可维护的代码结构。BEM的核心思想可以概括为:

  • Block(区块):代表一个功能相对完整、可复用的独立组件或页面区域。例如:page等。
  • Element(子元素):构成Block的不可分割的部分,没有独立的意义,依赖于所属的Block。例如:
    __hd、__bd等。
  • Modifier(修饰符):用于描述Block或Element的不同状态、外观或行为变化。例如:_primary、_default

解决新手常见问题

对于初学者而言,编写页面结构时往往会遇到两大挑战:一是页面结构设计不合理,导致代码难以维护;二是取类名时缺乏系统性,经常为每个元素独立命名,忽略了元素间的关联性。BEM正是解决这些问题的良方。

优化结构设计

采用BEM,开发者首先需要从宏观角度思考页面结构,将页面分解为一系列功能性的Block。这种自上而下的设计方式促使开发者在编码前先进行整体规划,从而避免了随意堆砌元素导致的结构混乱。例如,在设计一个博客文章列表时,可以将整个列表定义为一个Block(.post-list),每篇文章则是一个Element(.post-list__item)。

提升命名效率

BEM通过统一的命名规则,减少了命名时的不确定性。当确定了一个Block后,其内部的所有Element都通过双下划线__与Block相连,直观地表明了归属关系,如.post-list__title表示列表中文章的标题。这种方式不仅减少了取名时的思考成本,还使得代码具有高度的自我解释性,其他开发者甚至未来的自己都能快速理解代码意图。

实践案例分析

image.png

以创建微信小程序最近使用页面为例:

  1. 定义Block:首先确定这是一个页面组件,命名为.page;其中多设置了一个卡片组件,命名为.card

  2. 划分Element:页面分为上下两部分,分别命名.page__hd.page__bd;卡片也分为上下两部分,分别命名.card__hd.card__bd

  3. 应用Modifier:其中卡片中有不同小程序,通过Modifier来区分,如.item_cnsd.item_sfsd.item_jdkd.item_jdgw

实现代码如下:

html部分

<div class="page">
        <div class="page__hd">
            <p class="page__start">小程序</p>
            <div class="iconfont icon-sousuo"></div>
        </div>
        <div class="page__bd">
            <div class="card">
                <div class="card__hd">
                    <div class="card__title">最近使用</div>
                    <div class="card__more">更多></div>
                </div>
                <div class="card__bd">
                    <div class="card__item item_cnsd">
                        <span class="iconfont icon-cainiao" style="color: dodgerblue;"></span>
                        <div class="card__desc">菜鸟速递</div>
                    </div>
                    <div class="card__item item_sfsd">
                        <span class="iconfont icon-a-1667881343506" style="color:black;"></span>
                        <div class="card__desc">顺丰速递+</div>
                    </div>
                    <div class="card__item item_jdkd">
                        <span class="iconfont icon-jingdongkuaidi" style="color:red;"></span>
                        <div class="card__desc">京东快递</div>
                    </div>
                    <div class="card__item item_jdgw">
                        <span class="iconfont icon-jingdongsaomazhifu" style="color:red;"></span>
                        <div class="card__desc">京东购物</div>
                    </div>
                </div>
            </div>
        </div>
    </div>

css部分:

* {
    margin: 0;
    padding: 0;
    outline: 0;
    /*轮廓 不同的浏览器不一样*/
}

body,
html {
    height: 100%;
    /*按上去的高亮颜色 透明*/
    -webkit-tap-highlight-color: transparent;
}

body {
    /*为苹果用户优化 支持苹果特殊字体*/
    font-family: system-ui, -apple-system, sans-serif;

}

.page,
body {
    background-color: rgb(237, 237, 237);
}

.page {
    position: absolute;
    top: 0;
    left: 0;
    right: 0;
    bottom: 0;
    overflow-y: auto;
    /*page 一屏高度,用滚动条*/
    -webkit-overflow-scrolling: touch;
    /*让页面跟随手指滑动*/
    overflow-scrolling: touch;
}
.page__hd{
    display: flex;
    margin: 2% 6%;
    padding: 20px;

}
.page__start{
    font-weight: 700;
}
.icon-sousuo{
    margin-left: 75%;
    font-size: 20px;
}
.page__bd{
    border-radius:5%;
    margin: 2% 10%;
    background-color: white;
}
.card__hd{
    display: flex;
    padding: 10px;
    flex-direction: row;
    justify-content: space-between;
}
.card__bd{
    flex-direction: row;
    margin: 2%;
    display: flex;
    justify-content: space-between;   
}
.card__item{
    width: 20%;
    padding-bottom: 15px;
    display: flex;
    flex-direction: column;
}
.iconfont{
    display: flex;
    justify-content: center;
}
.iconfont:nth-child(3){
    background: blue;
}
.card__desc{
    font-size: 10px;
    display: flex;
    justify-content: center;
}
.card__more{
    right: 5%;;
}
.icon-cainiao{
    font-size: 30px;
}
.icon-a-1667881343506{
    font-size: 30px;
}
.icon-jingdongkuaidi{
    font-size: 30px;
}
.icon-jingdongsaomazhifu{
    font-size: 33px;
}

效果展示:

image.png

上图图标皆来自阿里图标库: iconfont-阿里巴巴矢量图标库
使用方式为下载代码方法,从上面网址下载。然后将其以css方式引入,使用类名进行添加。

结语

BEM命名规范不仅解决了新手开发者在页面构建过程中遇到的结构设计和命名难题,也为团队协作提供了坚实的基础。它强调了模块化思维,鼓励开发者以更系统化的方式组织代码,从而提高了开发效率和项目的可维护性。尽管初学时可能需要时间适应,但一旦掌握了BEM的精髓,你会发现它对提升代码质量和团队合作有着不可估量的价值。在快速迭代的Web开发环境中,遵循BEM规范,无疑是迈向高质量前端工程的重要一步。