🎉 用BEM玩转WEUI:给前端开发者的乐高式编程指南

86 阅读8分钟

🚨 一场关于"按钮"的命名战争💥

在某个阳光明媚的下午☀️,两位前端工程师正在会议室激烈辩论:"这个按钮的样式应该叫.btn-red还是.weui-btn_warn?" 这场看似普通的命名争论,实则是现代前端工程化理念的终极对决!⚔️

这时,一位穿着格子衬衫的架构师推了推眼镜👓:"兄弟们,你们是不是忘了BEM规范?" 于是会议室瞬间安静🤫,所有人都在笔记本上画起了乐高积木的结构图🧱——这就是今天我们要讲的WEUI框架BEM命名规范的奇妙缘分!🌟

01a69b6a9bf27c54fdd77d7efe0117f.png

成品展示🧩

8347d5e62c277219f25a5f4b2916f44.png


🧱 BEM规范:前端界的乐高积木哲学🧩

1. Block:你的乐高底板🏰

想象你在用乐高搭建城堡,每个独立的功能模块就是.weui-page这样的Block。它们像乐高底板一样,承载着整个建筑的结构:

/* Block示例 - 基础结构 */
.weui-page {
    max-width: 600px;
    margin: 0 auto;
    padding: 20px;
}

image.png

2. Element:可组合的零件🔧

.weui-page这个城堡里,我们需要各种装饰元素:标题栏是.weui-page__header,按钮是.weui-btn...

<!-- Element示例 - 头部结构 -->
<div class="weui-page__header">
   <h1 class="weui-page__title">WEUI 组件示例</h1> 
   <p class="weui-page__desc">基于BEM命名规范的微信风格UI组件</p>
</div>

image.png

3. Modifier:魔法修饰符🔮

现在我们给乐高积木施魔法!通过.weui-btn_primary这样的Modifier,就能让普通按钮变身超级按钮:

<!-- Modifier魔法 -->
<button class="weui-btn weui-btn_primary">主要按钮</button>
<button class="weui-btn weui-btn_default">默认按钮</button>

image.png

🌟 BEM命名规范的具体好处✨

绝技名称技术效果实战案例
命名防冲突通过Block+Element结构杜绝类名冲突.weui-page__title
状态独立性Modifier修饰符让状态独立存在.weui-btn_disabled
组件可移植Block级组件可独立开发、测试、部署.weui-form
语义化增强类名直接表达组件结构.weui-cell__hd
维护成本低修改一个组件不会影响其他组件.weui-dialog__ft

🧪 WEUI实战实验室🧪

实验一:按钮变形记🚀

🧬 按钮DNA重组实验🧬

WEUI的按钮就像乐高积木,通过不同"基因"组合可以进化出多种形态:

<!-- 基础按钮 -->
<button class="weui-btn">普通按钮</button>

<!-- 主按钮 -->
<button class="weui-btn weui-btn_primary">主要按钮</button>
<!-- 
    DNA解析:
    Block: weui-btn
    Modifier: _primary
    功能:绿色背景+白色文字
-->

<!-- 警告按钮 -->
<button class="weui-btn weui-btn_warn">警告按钮</button>
<!-- 
    DNA解析:
    Block: weui-btn
    Modifier: _warn
    功能:红色背景+白色文字
-->

<!-- 加载按钮 -->
<button class="weui-btn weui-btn_primary weui-btn_loading">加载中</button>
<!-- 
    DNA解析:
    Block: weui-btn
    Modifier: _primary + _loading
    功能:绿色背景+旋转加载动画
-->

背后的CSS魔法:

/* 基础按钮样式 */
.weui-btn {
    display: inline-block;
    padding: 8px 16px;
    border-radius: 4px;
    font-size: 14px;
    text-align: center;
    cursor: pointer;
    border: none;
    transition: all 0.3s;
    margin: 5px;
}

/* 加载状态动画 */
@keyframes weui-loading {
    from { transform: rotate(0deg); }
    to { transform: rotate(360deg); }
}

/* 加载按钮样式 */
.weui-btn_loading::after {
    content: "";
    position: absolute;
    width: 16px;
    height: 16px;
    top: 50%;
    left: 50%;
    margin: -8px 0 0 -8px;
    border: 2px solid #fff;
    border-radius: 50%;
    border-right-color: transparent;
    animation: weui-loading 0.8s linear infinite;
}

image.png

实验二:表单变形实验⚙️

🧪 表单组件的进化之路🧬

<div class="weui-form">
  <!-- 表单头部 -->
  <div class="weui-form__hd">
    <h2 class="weui-form__title">用户登录</h2>
  </div>
  
  <!-- 表单主体 -->
  <div class="weui-form__bd">
    <div class="weui-cell">
      <div class="weui-cell__hd"><label class="weui-label">用户名</label></div>
      <div class="weui-cell__bd">
        <input class="weui-input" type="text" placeholder="请输入用户名">
      </div>
    </div>
    
    <div class="weui-cell">
      <div class="weui-cell__hd"><label class="weui-label">密码</label></div>
      <div class="weui-cell__bd">
        <input class="weui-input" type="password" placeholder="请输入密码">
      </div>
    </div>
  </div>
  
  <!-- 表单底部 -->
  <div class="weui-form__ft">
    <button class="weui-btn weui-btn_primary">登录</button>
  </div>
</div>

DNA解析:

  • Block: .weui-form 作为表单容器
  • Elements:
    • __hd(头部)
    • __bd(主体)
    • __ft(底部)
  • 嵌套结构.weui-cell 是表单项的基本单元

image.png

实验三:单元格进化实验🌌

🧬 单元格组件的魔幻变身✨

<div class="weui-cells">
  <h3 class="weui-cells__title">个人信息</h3>
  
  <div class="weui-cell">
    <div class="weui-cell__hd">
      <img src="avatar.png" alt="头像" class="weui-cell__img">
    </div>
    <div class="weui-cell__bd">
      <p>用户昵称</p>
    </div>
    <div class="weui-cell__ft">
      <p>编辑</p>
    </div>
  </div>
  
  <div class="weui-cell">
    <div class="weui-cell__hd">
      <span class="weui-icon weui-icon_arrow"></span>
    </div>
    <div class="weui-cell__bd">
      <p>账号设置</p>
    </div>
  </div>
</div>

DNA解析:

  • 基本结构.weui-cell 由三个部分组成
    • __hd(头部):常放图标
    • __bd(主体):放主要文本
    • __ft(尾部):放辅助信息
  • 修饰符.weui-cell__img 专门处理图片尺寸

image.png


实验四:导航栏变形实验🧭

🧪 导航栏的七十二变🌀

<div class="weui-navbar">
  <div class="weui-navbar__item weui-navbar__item_active">首页</div>
  <div class="weui-navbar__item">分类</div>
  <div class="weui-navbar__item">购物车</div>
  <div class="weui-navbar__item">我的</div>
</div>

CSS魔法:

.weui-navbar {
    display: flex;
    background-color: #f8f8f8;
    border-bottom: 1px solid #e6e6e6;
}

.weui-navbar__item {
    flex: 1;
    text-align: center;
    padding: 15px 0;
    color: #999;
}

.weui-navbar__item_active {
    color: #07c160;
    font-weight: bold;
    border-bottom: 2px solid #07c160;
}

DNA解析:

  • Block: .weui-navbar 作为导航容器
  • Elements:
    • __item(导航项)
    • __item_active(激活状态修饰符)
  • 交互设计:通过激活状态切换实现导航栏切换效果

image.png

实验五:弹窗变形实验🎩

🧬 弹窗组件的魔法变身🧙‍♂️

<div class="weui-mask" style="display:none;"></div>
<div class="weui-dialog" style="display:none;">
  <div class="weui-dialog__hd">
    <strong class="weui-dialog__title">提示</strong>
  </div>
  <div class="weui-dialog__bd">
    确定要删除这个文件吗?
  </div>
  <div class="weui-dialog__ft">
    <button class="weui-dialog__btn weui-dialog__btn_default">取消</button>
    <button class="weui-dialog__btn weui-dialog__btn_primary">确定</button>
  </div>
</div>

DNA解析:

  • 遮罩层.weui-mask 实现半透明背景
  • 对话框结构
    • __hd(标题区域)
    • __bd(内容区域)
    • __ft(按钮区域)
  • 交互设计:通过显示/隐藏实现弹窗效果

image.png

🧠 高级进阶:BEM与组件化开发的化学反应🔥

当BEM遇到组件化开发,就像乐高遇到了3D打印机🖨️。我们可以将.weui-page拆解成多个可复用的组件:

// 伪代码示例
const WeuiPage = {
  header: {
    title: '.weui-page__title',
    desc: '.weui-page__desc'
  },
  body: {
    button: {
      primary: '.weui-btn_primary',
      default: '.weui-btn_default'
    }
  }
}

📌 结语:成为BEM大师的七个习惯🎓

  1. 每天坚持用BEM命名📚
  2. 给类名加注释(像给乐高零件贴标签)🏷️
  3. 定期清理无用类名🧹
  4. 学会用Modifier做样式微调🖌️
  5. 掌握Element嵌套技巧📦
  6. 理解Block的独立性🧩
  7. (最重要的)保持对BEM的敬畏之心🙏

📎 附录:完整代码示例📎

weui.css📜

/**
 * WEUI 基础样式
 * 基于BEM命名规范的微信风格UI框架
 * Block: weui-page
 * Element: weui-page__header, weui-page__title, weui-page__desc
 * Modifier: weui-btn_primary, weui-btn_default 等
 */

/* 页面容器样式 */
.weui-page {
    /* 设置最大宽度,确保在大屏幕上有良好的阅读体验 */
    max-width: 600px;
    /* 水平居中 */
    margin: 0 auto;
    /* 内边距,提供舒适的视觉空间 */
    padding: 20px;
    /* 使用系统默认字体,确保跨平台显示一致性 */
    font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Oxygen, Ubuntu, Cantarell, "Open Sans", "Helvetica Neue", sans-serif;
}

/* 页面头部样式 */
.weui-page__header {
    /* 文本居中对齐 */
    text-align: center;
    /* 底部外边距,与内容区域保持适当间距 */
    margin-bottom: 30px;
}

/* 页面标题样式 */
.weui-page__title {
    /* 设置合适的字体大小 */
    font-size: 24px;
    /* 深灰色文本,提供良好的可读性 */
    color: #333;
    /* 底部外边距,与描述文本保持间距 */
    margin-bottom: 10px;
}

/* 页面描述文本样式 */
.weui-page__desc {
    /* 较小的字体大小,区分于标题 */
    font-size: 14px;
    /* 浅灰色文本,形成层次感 */
    color: #666;
}

/* 按钮基础样式 */
.weui-btn {
    /* 行内块级元素,允许设置宽高 */
    display: inline-block;
    /* 内边距,提供舒适的点击区域 */
    padding: 8px 16px;
    /* 圆角边框 */
    border-radius: 4px;
    /* 合适的字体大小 */
    font-size: 14px;
    /* 文本居中 */
    text-align: center;
    /* 鼠标指针样式 */
    cursor: pointer;
    /* 移除默认边框 */
    border: none;
    /* 添加过渡效果,使状态变化更平滑 */
    transition: all 0.3s;
    /* 按钮之间的间距 */
    margin: 5px;
}

/* 按钮修饰符样式 */

/* 主要按钮 - 绿色主题 */
.weui-btn_primary {
    background-color: #07c160; /* 微信绿 */
    color: #fff;
}

/* 默认按钮 - 灰色主题 */
.weui-btn_default {
    background-color: #f7f7f7;
    color: #333;
    border: 1px solid #ddd;
}

/* 警告按钮 - 红色主题 */
.weui-btn_warn {
    background-color: #fa5151;
    color: #fff;
}

/* 禁用状态 */
.weui-btn_disabled {
    /* 降低透明度表示禁用状态 */
    opacity: 0.6;
    /* 更改鼠标指针样式 */
    cursor: not-allowed;
}

/* 加载状态 */
.weui-btn_loading {
    /* 相对定位,用于放置加载动画 */
    position: relative;
    /* 隐藏按钮文本 */
    color: transparent;
}

/* 加载动画样式 */
.weui-btn_loading::after {
    content: "";
    position: absolute;
    /* 设置加载图标大小 */
    width: 16px;
    height: 16px;
    /* 居中定位 */
    top: 50%;
    left: 50%;
    margin: -8px 0 0 -8px;
    /* 创建圆形边框 */
    border: 2px solid #fff;
    border-radius: 50%;
    /* 创建缺口效果 */
    border-right-color: transparent;
    /* 添加旋转动画 */
    animation: weui-loading 0.8s linear infinite;
}

/* 镂空按钮基础样式 */
.weui-btn_plain {
    background-color: transparent;
    border: 1px solid #ddd;
}

/* 镂空主按钮样式 */
.weui-btn_plain_primary {
    color: #07c160;
    border-color: #07c160;
}

/* 加载动画关键帧定义 */
@keyframes weui-loading {
    from {
        transform: rotate(0deg);
    }
    to {
        transform: rotate(360deg);
    }
} 

weui.html🌐

<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <!-- 设置视口,确保在移动设备上正确显示 -->
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>WEUI 示例</title>
    <!-- 引入WEUI样式文件 -->
    <link rel="stylesheet" href="weui.css">
</head>
<body>
    <!-- 页面容器,使用BEM命名规范 -->
    <div class="weui-page">
        <!-- 页面头部区域 -->
        <div class="weui-page__header">
            <!-- 页面标题 -->
            <h1 class="weui-page__title">WEUI 组件示例</h1>
            <!-- 页面描述文本 -->
            <p class="weui-page__desc">基于BEM命名规范的微信风格UI组件</p>
        </div>

        <!-- 页面内容区域 -->
        <div class="weui-page__content">
            <!-- 基础按钮示例 -->
            <h2>按钮示例</h2>
            <div>
                <!-- 主要按钮 -->
                <button class="weui-btn weui-btn_primary">主要按钮</button>
                <!-- 默认按钮 -->
                <button class="weui-btn weui-btn_default">默认按钮</button>
                <!-- 警告按钮 -->
                <button class="weui-btn weui-btn_warn">警告按钮</button>
            </div>

            <!-- 禁用状态按钮示例 -->
            <h2>禁用状态</h2>
            <div>
                <!-- 禁用状态的主按钮 -->
                <button class="weui-btn weui-btn_primary weui-btn_disabled">禁用按钮</button>
            </div>

            <!-- 加载状态按钮示例 -->
            <h2>加载状态</h2>
            <div>
                <!-- 加载状态的主按钮 -->
                <button class="weui-btn weui-btn_primary weui-btn_loading">加载中</button>
            </div>

            <!-- 镂空按钮示例 -->
            <h2>镂空按钮</h2>
            <div>
                <!-- 默认镂空按钮 -->
                <button class="weui-btn weui-btn_plain">镂空按钮</button>
                <!-- 主要镂空按钮 -->
                <button class="weui-btn weui-btn_plain_primary">镂空主按钮</button>
            </div>
        </div>
    </div>
</body>
</html> 

🎉 恭喜你!现在你已经掌握了BEM与WEUI的完美结合技巧!记得在实践中多加练习,你的代码世界将会变得更加整洁有序!🌟