BEM修饰符不能直接用view--enter/view--leave,因它们是瞬时动画帧而非稳定逻辑状态;应使用view--entering/view--leaving(过渡中)和view--in/view--out(终态),且状态必须作用于块级view而非元素如view__content。

如何用 BEM 修饰符表达视图切换的 enter/leave 状态
不能直接用 view--enter 或 view--leave 当作修饰符——BEM 不支持“瞬时过渡态”作为修饰符,因为修饰符必须代表可稳定读取、可被 JS 显式控制、可被 DevTools 检查的**逻辑状态**,而非 CSS 动画中间帧。
Enter/Leave 是动画触发时机,不是组件固有状态。强行塞进修饰符会导致 class 频繁增删、样式不可预测、服务端渲染(SSR)与客户端不一致。
- 正确做法:用
view--in表示“已进入并就绪”,view--out表示“已退出并卸载” -
view--entering和view--leaving才是合法修饰符,仅在 transition 过程中短暂存在,由 JS 在transitionstart前添加、transitionend后移除 - 所有动画必须基于这四个类组合编写,例如:
.view--entering控制入场起始样式,.view--in.view--entering控制入场结束帧
为什么不能把 enter/leave 写成 .view__content--enter
元素级修饰符(view__content--enter)违反 BEM 的语义分层原则:视图切换是整个 view 块的生命周期行为,不是某个子内容的独立变体。一旦把状态下沉到元素,就会导致:
- JS 必须同时操作
view块和其内部多个__content、__header类,耦合度飙升 - CSS 选择器权重失衡,比如
.view__content--enter可能意外覆盖.view--entering的 transform 设置 - 无法统一响应路由变化:Vue Router 的
beforeEach或 React Router 的useNavigation只能可靠地控制块级 class
记住:__ 连接的是结构从属关系,不是状态归属关系。状态属于块,不是它的零件。
Enter/Leave 动画的 class 切换顺序必须严格
常见错误是 JS 在路由跳转后立刻加 view--entering,但此时旧视图还没移除 view--in,造成两个视图同时拥有 opacity:1,视觉重叠。
标准流程应为:
- 新视图挂载后,先设
class="view view--entering"(初始透明+位移) - 监听
transitionend,移除view--entering,添加view--in - 旧视图在导航确认后,立即加
view--leaving,再移除view--in - 等
transitionend触发,彻底移除旧视图 DOM 或清空 class
漏掉任一环节,都会让 view--entering 或 view--leaving 残留在 DOM 上,成为难以排查的“幽灵 class”。
SSR 场景下 view--in 的服务端预设风险
服务端首次渲染必须只输出 view--in,绝不能输出 view--entering 或 view--leaving——这些是纯客户端过渡态,服务端无 transition 上下文,硬塞进去会导致 hydration 失败或 FOUC。
更隐蔽的问题是:如果服务端根据 URL 渲染了 A 视图(带 view--in),但客户端路由守卫重定向到 B 视图,而 JS 未及时清理 A 的 view--in,就会出现两个 view--in 并存。
解决方案只有两个:
– 所有视图容器统一用 data-view-id 标记,JS 初始化时先清空所有非当前 ID 的 view--in
– 使用 CSS 容器查询(@container (state: active))替代部分 class 控制,降低 JS 干预强度
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











