判断dom节点是block还是element关键看其能否脱离上下文独立存在、复用或单独测试:user-card是block,user-card__avatar是element;block命名须小写短横线,禁用位置词与容器词;bem的__和--不可替换或省略,否则工具链失效;scss禁用嵌套__选择器;js类名应封装生成,避免手拼;html中element必须与block共存;pre-commit需精准校验暂存区css文件。

怎么判断一个DOM节点该叫Block还是Element
关键看它能不能脱离当前上下文独立存在、复用或被单独测试。user-card是Block,因为卡片能出现在首页、搜索页、详情页;user-card__avatar是Element,删掉头像,卡片还能渲染,但删掉整个user-card,头像就失去语义锚点。
常见误判:homepage-banner、top-nav、sidebar-menu——这些词里混了位置信息,不是Block本身,应抽象为carousel、main-navigation、vertical-menu。
- Block名必须小写+短横线:
search-form✅,UserForm❌,user_form❌ - 含“容器”“wrapper”“section”的名字大概率是伪Block,比如
content-wrapper,真正该拆的是它里面的article-list或pagination - 如果某个“元素”在多个Block中复用(如
icon出现在按钮、导航、卡片),它大概率该是独立Block:icon,而不是谁的__icon
为什么__和--不能替换成-或省略
这不是风格问题,是工具链识别BEM结构的硬性锚点。漏写、错写会直接导致stylelint-selector-bem-pattern失效、VS Code插件无法高亮、构建时样式提取逻辑出错。
错误写法:.button__icon_error(单_代替--)、.card-header--large(漏一个_)、.card__body--compact--dark(嵌套修饰符)。
-
__必须严格连接块与直系子元素,product-card__image__caption非法,应拆成product-card__image和product-card__caption -
--只能挂载在Block或Element节点上,button--primary__text是错的;合法组合只有button--disabled(块级)或button__label--hidden(元素级) - SCSS里禁用
&__image { &__caption { } },编译后是后代选择器,破坏BEM平级隔离
JS中动态拼接类名最容易踩哪些坑
手拼字符串看着快,实际在CI环境下极易因空格、连字符、大小写漏写而挂掉。本地开发跑得通,Linux构建直接报错。
危险写法:className={`button button--${variant} ${hasIcon ? 'button__icon' : ''}`}——缺空格、button__icon脱离Block、无防错。
- 推荐封装常量:
const BLOCK = 'search-form'; const cn = (e, m) => `${BLOCK}${e ? '__' + e : ''}${m ? '--' + m : ''}`,调用cn('input', 'disabled')得到search-form__input--disabled - Modifier名必须表达意图或状态(
button--loading),而非纯视觉描述(button--red),否则换主题时无法映射逻辑 - HTML中
element不能单独使用:class="card__title"无效,必须同时有class="card card__title"
pre-commit钩子里stylelint只校验暂存区CSS文件
直接跑stylelint "**/*.css"会扫全量文件,既慢又误报。CI或本地提交时,真正要检查的只是git add进暂存区的那几个改动文件。
实操脚本关键三步:
- 用
git diff --cached --name-only --diff-filter=ACM提取本次提交新增/修改/重命名的文件 - 加
| grep '\.css$'过滤出CSS类型(注意单引号防shell展开) - 开头必须
cd $(git rev-parse --show-toplevel)切到仓库根,否则stylelint找不到配置文件
漏掉任一环,钩子要么不生效,要么报路径错误。尤其cd这步,本地开发常因工作目录在子文件夹而失败。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











