web 前端组件拆分与复用策略
组件拆分原则(原子设计思想进阶)
原子级组件
- 基础 UI 元素:按钮、输入框、图标等
- 特点:无状态或简单状态,零业务逻辑
- 示例:
<Button>、<Input>
分子级组件
- 原子组件的组合:搜索框 = 输入框 + 按钮
- 特点:封装简单交互逻辑,可复用
- 示例:
<SearchBar onSearch={callback}>
有机体级组件
- 业务模块:商品卡片 = 图片 + 标题 + 价格 + 评分
- 特点:包含业务数据结构和样式,部分复用
- 示例:
<ProductCard data={product}>
模板级组件
- 页面骨架:布局结构(Header/Footer/Sidebar)
- 特点:通过插槽(Slots)组织区域
- 示例:
<PageLayout> <template #header><Header /></template> <template #content><RouterView /></template> </PageLayout>
页面级组件
- 路由对应视图:组合多个有机体
- 特点:包含数据获取和状态管理,不可复用
- 示例:/product-detail 页面
复用策略金字塔(优先级从高到低)
配置化驱动(最佳实践)
- 通过 Props 控制行为和样式
- 示例:
<Table columns={[...]} data={[...]} pagination={{ pageSize: 10 }} />
组合模式(React/Vue 核心思想)
- 使用 children 或插槽注入内容
- 示例:
<Modal> <CustomForm /> {/* 内部内容可自由替换 */} </Modal>
自定义 Hooks / Composables(逻辑复用)
- 抽离通用逻辑(如数据请求、拖拽逻辑)
- 示例:
// 复用数据请求逻辑 const { data, loading } = useFetch('/api/data');
高阶组件/Render Props(复杂场景)
- 适用于跨组件逻辑复用(如权限校验)
- 示例:
<AuthGuard role="admin"> <AdminPanel /> </AuthGuard>
全局组件库(基础组件复用)
- 将原子/分子组件发布为独立 npm 包
- 维护统一的版本和文档(如 Storybook)
关键决策点
何时拆分?
| 场景 | 解决方案 |
|---|---|
| 相同 UI 出现 3 次以上 | 抽取为可配置组件 |
| 组件代码 > 300 行 | 按功能拆分子组件 |
| 多个文件引用同一段逻辑 | 抽离为自定义 Hook |
避免过度拆分
// ❌ 错误示范:无意义的原子化
const RedText = ({ children }) => <p style={{ color: 'red' }}>{children}</p>;
// ✅ 正确做法:通过 Props 控制
const Text = ({ color, children }) => <p style={{ color }}>{children}</p>;
可维护性保障
- 单一职责原则
- 每个组件只解决一个问题(如 PriceDisplay 只处理价格格式化)
- 受控/非受控模式
- 同时支持受控(value + onChange)和非受控(defaultValue)行为
- 严格的 TypeScript 类型
interface ButtonProps { variant: 'primary' | 'ghost'; // 明确可选值 size?: 'sm' | 'md'; // 可选属性 onClick: () => void; // 函数类型 } - 文档驱动开发
- 使用 Storybook 或 dumi 可视化组件用例
- 自动生成 Props 文档
业务场景实践
场景:电商商品卡片
// 1. 原子组件
<Image src={...} lazyLoad />
// 2. 分子组件
<PriceDisplay value={99} currency="CNY" />
// 3. 有机体组件(业务卡片)
<ProductCard
data={product}
// 差异化配置
showDiscountBadge={true}
layout="vertical"
/>
// 4. 通过组合扩展功能
<ProductCard>
<Slot name="footer">
<CountdownTimer endTime={...} /> {/* 定制化内容 */}
</Slot>
</ProductCard>
避免的常见陷阱
- Prop Drilling 地狱
- 使用 Context/状态管理库传递深层数据
- 滥用全局状态
- 表单状态应优先保留在组件内部
- 忽略性能优化
- 对大数据列表使用虚拟滚动
- 使用 React.memo/useMemo 减少渲染
- 组件与业务逻辑强耦合
- 错误示例:
<UserCardWithOrderHistory /> - 正确方案:
<UserCard extraContent={<OrderHistory />}>
- 错误示例:
总结:组件化心智模型
[ 原子组件 ] → [ 分子组件 ] → [ 业务组件 ]
↑ ↑ ↑
基础UI库 逻辑复用 页面组装
遵循 「高内聚、低耦合」 原则:
- 向上通过 Props 控制行为
- 向下通过 Slots 提供扩展能力
- 横向通过 Hooks 复用逻辑
通过分层设计和合理的复用策略,可显著提升代码可维护性和团队协作效率。