useClassComputed
在该组件库的架构中,Hooks 是逻辑层的核心承载者。它们不是组件的附属逻辑,而是独立、可复用的抽象单元,负责将重复出现的交互与计算模式彻底从组件中剥离。
这正是“层分离”思想的直接体现:
- 结构层:仅负责 DOM 布局
- 表现层:仅负责样式注入
- 逻辑层:由 Hooks 统一管理
Hooks 的存在,让组件实现变得极简——组件只需声明所需逻辑,其余响应式计算与驱动全部交给 Hooks 处理。
动态类名计算 Hook
痛点来源
开发 UI 组件时,最常见的重复工作之一便是根据 props 动态生成类名。例如:
size="large"→ 需要添加xxx--largedisabled={true}→ 需要添加xxx--disabledround={true}→ 需要添加xxx--round
如果每个组件都自行实现此类逻辑,将导致:
- 代码高度冗余
- 命名规范容易不一致
- 可能遗漏响应式更新
- 主题或命名规范变更时,需要逐个组件修改,维护成本极高
设计目标
useClassComputed 的目标是:提供一套统一、类型安全、可配置的机制,彻底解决所有组件的动态类名生成需求,并将这一逻辑从组件内部完全剥离。
核心特性
| 特性 | 说明 |
|---|---|
| 响应式输出 | 返回 ComputedRef<string[]>,随 props 变化自动更新,完美契合 Vue 响应式系统 |
| BEM-like 约定 | 默认采用 ${baseClass}--${modifier} 格式,确保类名语义清晰、可预测 |
| 双轨生成机制 | propClasses:针对带值属性(如 size、type)flagClasses:针对布尔标志(如 disabled、round) |
| 高度可定制 | 通过 classNameFormatter 支持自定义格式化函数,适应多级 BEM、主题前缀等场景 |
| 类型安全 | 泛型 <T> 与组件 props 强绑定,提供完整的 TypeScript 类型推导与提示 |
| 明确边界 | 不绑定 DOM、不处理样式冲突、不涉及副作用(如事件监听或 DOM 查询) |
设计价值
useClassComputed 看似简单,却精准解决了组件库中最常见的“样式逻辑耦合”问题。它将类名计算逻辑集中于一处,确保:
命名规范全局统一 类名生成行为可预测、可配置 组件代码极度精简(无需手动拼接 class) 易于未来演进(如接入主题 token、自动暗黑模式后缀等)