价格组件应按业务语义拆分为 .product-card(主块)、.price-display(复用复杂价格逻辑的独立块)和 .price-badge(高频复用促销角标)三个块;划线价、现价、单位通常为 .price-display 的元素,仅在需独立动效或国际化时升为块;状态修饰符须表达业务意图如 --pending、--unavailable;响应式通过显式修饰符如 --compact 实现。
看到 .price 就直接当 block 用,是 BEM 最常见的误判起点。真实电商场景中,“价格”几乎从不单独存在:它总和商品卡片、促销标签、划线价、单位(如“¥/件”)耦合。强行塞进一个 .price 块,会导致后续加“会员价”“预售价”“阶梯价”时不断打补丁,类名爆炸。
正确做法是按业务语义边界切分:
.product-card 是主块——价格是它的一部分,但不是全部.price-display 是独立块——当价格逻辑复杂(含多状态、动态计算、货币切换),且在商品列表、购物车、订单确认页三处复用时才成立.price-badge 是另一个块——如果“限时5折”这类促销角标在多个模块里高频复用,它就不该是 .product-card__badge,而应自立门户判断标准很直白:删掉父容器,这个价格信息还能否被其他模块原样复用?能,就是块;不能,它只是元素。
划线价(.old-price)、现价(.current-price)、单位(.price-unit)在绝大多数情况下都属于 .price-display 的元素,写成 .price-display__old、.price-display__current、.price-display__unit 即可。但有两个例外必须升为块:
.strikethrough-price 块.price-unit 块,而非元素关键陷阱:.price-display__current__icon 这种三层嵌套是反模式。如果现价旁要加个“VIP”徽章,正确解法是 .price-display__current + 独立的 .vip-badge 块,而不是把它塞进现价元素里。
修饰符名必须表达业务意图,而非前端技术状态。以下写法全是错的:
.price-display--loading → 加载是过程,用户不关心;应为 .price-display--pending(价格尚未确认)或 .price-display--calculating(正在实时计算).price-display--error → 错误是技术归因;应为 .price-display--unavailable(库存不足无法报价)或 .price-display--restricted(区域限购).price-display--red → 颜色是视觉实现;应为 .price-display--discounted 或 .price-display--final-sale
修饰符必须可枚举、可预测。设计换主题时,改 --discounted 对应的 CSS 变量即可,不用全局搜 --red 替换。
BEM 不允许在 SCSS 中写 .price-display { @media (max-width: 768px) { &__unit { display: none; } } }。这种写法会让 .price-display__unit 在小屏下“消失”,但类名本身没变——破坏了“类名即状态”的契约。
正确方案是用修饰符显式声明响应式变体:
.price-display--compact:小屏下折叠单位、合并划线价与现价间距.price-display--stacked:超小屏下让现价、划线价垂直堆叠JS 根据 viewport 宽度切换类名,CSS 只管样式。这样 HTML 结构稳定,服务端渲染也无需感知断点逻辑。容易忽略的是:这些修饰符必须在所有使用 .price-display 的地方统一注入,否则会出现“同一组件在首页是 compact,在搜索页却是默认态”的不一致。
tlwdr7650路由器没有wps按钮(tlwdr7650路由器没有wps按钮怎么办)
tlwdr7632扩展器电脑怎么设置(tlwdr7632扩展器电脑设置方法)
tlwda6332re安装教程(tlwda6332re如何安装)
tlwdr7632扩展器手机怎么设置(tlwdr7632扩展器手机设置方法)
tlxdr3010怎么设置网速快(tlxdr3010网速快设置方法)
tlwdr5620易展版怎么克隆(tlwdr5620易展版克隆方法)