calendar-grid 必须是独立 Block,因其具备跨场景复用性;date-picker 仅负责容器控制、触发入口和弹层挂载,不管理日期状态;所有状态类必须归属 calendar-grid 自身,命名严格遵循 BEM 原子修饰符规则。

日历组件的 BEM 体系必须拆成独立 Block,不能用 date-picker__calendar__day 这类嵌套命名——它既违反 BEM 单层元素规则,又锁死 calendar-grid 的复用能力。
为什么 calendar-grid 必须是独立 Block 而非 element
因为日历网格本身具备跨场景复用性:行程视图、月度统计面板、甚至后台排班表都可能直接引用同一套格子逻辑。一旦把它写成 date-picker__calendar,就等于在语义上宣告“它只属于日期选择器”,后续想抽离时要重写样式、JS 状态管理、无障碍属性(aria-current、aria-disabled)全部绑定逻辑。
-
calendar-grid是一个完整 Block,对应独立文件calendar-grid/calendar-grid.scss,只允许出现以calendar-grid开头的类名 -
date-picker__panel只负责容器定位、弹层层级、年月切换区布局,不渲染任何日期格子 - HTML 中直接嵌入:
,而非
date-picker 的职责边界怎么划才不越界
date-picker 只管三件事:外层容器控制(宽度、禁用态、表单集成如 name / required)、触发入口封装、弹层挂载点。它不该知道“今天是几号”或“哪天被选中”,这些状态全由 calendar-grid 自己管理并暴露语义类。
-
date-picker__trigger:仅含输入框 + 图标,响应点击/键盘事件,不渲染日历 DOM -
date-picker__panel:绝对定位容器,内部可嵌year-selector和month-selector两个独立 Block,不写date-picker__year - 禁止出现
date-picker__calendar__day--selected—— 这种写法让 JS 控制逻辑和 CSS 作用域同时失控
日期状态类该挂在哪一层、怎么命名才安全
所有日期状态必须由 JS 显式控制类名,且严格归属到对应 Block 或其直属 Element。伪类(:disabled、:checked)不可靠,因为日历 DOM 是完全自定义的。
-
calendar-grid__day--today:仅标记“今日”,不带交互,CSS 只控制背景色 -
calendar-grid__day--selected:JS 切换,支持多选叠加(如calendar-grid__day--selected calendar-grid__day--range-start) -
calendar-grid__day--disabled:基于min/max或业务规则禁用,CSS 控制opacity和pointer-events: none - 不要用
is-前缀代替 -- 修饰符,BEM 工具链(如 stylelint-selector-bem-pattern)默认不校验is-,容易漏检
SCSS 里怎么写才不破坏 BEM 扁平结构
空格嵌套是最大陷阱。.calendar-grid { &__day { .icon { } } } 编译出的是 .calendar-grid__day .icon,这是后代选择器,一旦图标被移到别处或复用,样式立即失效。
- 只用
&__和&--,禁用任何空格:&__day✅,&__day .icon❌ - 真需控制子元素样式(比如不同主题下图标颜色),优先用属性选择器:
[data-icon="date"],而不是靠类名猜结构 - 所有修饰符必须原子化:
--today✅,--date-today❌;--selected✅,--is-selected❌
最容易被忽略的是:BEM 不是给 class 加前缀,而是用命名把组件的合法结构、状态边界、复用契约提前钉死。一旦允许 icon--sm 这种脱离 Block 的类名,或者靠 [class*="--"] 模糊匹配提取修饰符,整个约束体系就塌了。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











