# 小程序统一组件库设计规格 > 日期: 2026-05-16 | 状态: 编写中 | 方案: 三层架构(原子 + 模式 + Hook) --- ## 1. 背景与问题 小程序端 66 个页面存在严重 UI 不统一:59 页手写骨架、119 处卡片重写、9+ 列表页无模板、关怀模式未覆盖 doctor 端。根因是缺少组件级统一抽象。 目标:改 1 处组件 = 全部页面同步;页面代码减少 ~70%;关怀 100% 覆盖。 ## 2. 设计决策 三层架构 | 仅小程序端 | 温润东方风 | 组件级关怀 | 渐进迁移 ## 3. 目录结构 components/ui/ (原子) → components/patterns/ (组合) → hooks/useListPage.ts (Hook) ## 4. 第 1 层:原子组件 **PageShell** — 页面容器。padding 语义化(none/sm/md/lg),safeBottom,scroll 包裹。 **ContentCard** — 卡片。3 种 variant,统一圆角/阴影/触摸反馈。 **StatusTag** — 状态标签。内置 5 色映射,pill 圆角。 **SectionTitle** — 段落标题。赤土橙竖线装饰。 **LoadingCard** — 骨架屏。与 ContentCard 同尺寸。 ## 5. 第 2 层:组合模式 **PageHeader** — 页面顶部(title + back + actions)。 **SearchSection** — 搜索区域(搜索框 + 可选筛选标签)。 **CardList** — 列表容器(自动处理 loading/error/empty)。 **PaginationBar** — 分页控制(替代 2 种命名体系)。 ## 6. 第 3 层:useListPage Hook 封装分页/搜索/筛选/加载/空状态。返回 listPageProps 可直接展开给组合组件。列表页从 ~120 行降至 ~35 行。 --- ## 7. 关怀模式集成 ### 现状问题 当前关怀模式通过 `elder-mode.scss` 全局 CSS 覆写实现,存在 3 个问题: 1. 按类名匹配,新增页面不用正确类名就漏掉 2. doctor 端页面完全不在覆写范围内 3. 每次改组件样式都要同步改 elder-mode.scss ### 新方案:组件级自适应 每个原子组件内部全部读取 CSS 变量,关怀模式只需改变量值: 1. **扩展 tokens.scss** — 新增结构化 Token: ``` --tk-card-bg: #fff // 卡片背景 --tk-card-padding: 24px // 卡片内间距 --tk-card-radius: 16px // 卡片圆角 --tk-gap-sm: 12px // 小间距 --tk-gap-md: 16px // 中间距 --tk-gap-lg: 24px // 大间距 --tk-page-padding: 24px // 页面内间距 --tk-touch-feedback-opacity: 0.85 // 触摸反馈透明度 ``` 2. **原子组件全部读变量** — ContentCard 的 padding 使用 `var(--tk-card-padding)`,border-radius 使用 `var(--tk-card-radius)` 3. **elder-mode.scss 只覆写变量值**: ```scss .elder-mode { --tk-card-padding: 32px; // 24px → 32px --tk-card-radius: 20px; // 16px → 20px --tk-gap-md: 20px; // 16px → 20px --tk-page-padding: 32px; // 24px → 32px // ... 已有字号/触控变量保持不变 } ``` 4. **新页面自动获得关怀支持** — 只要使用原子组件,无需额外代码 5. **精简 elder-mode.scss** — 只保留页面级特殊覆写(如体征网格 2 列→1 列),不再需要组件级覆写 --- ## 8. 迁移策略 ### Phase 1:创建组件 + Token 扩展(~2天) - 扩展 tokens.scss 新增 `--tk-card-*`、`--tk-gap-*`、`--tk-page-*` 等结构化 Token - 实现 5 个原子组件 + 4 个组合组件 + useListPage Hook - 每个组件编写基本测试(渲染/Props/变体) - **不动任何现有页面**,新组件与旧代码并行 ### Phase 2:迁移 doctor 端列表页(~1.5天) - 选择 patients 列表页做试点 — 完整迁移 + 截图对比验证 - 批量迁移剩余 8 个列表页:dialysis, prescription, report, alerts, consultation(doctor), followup, article, consultation(患者) - 每页迁移后:截图对比 → 功能验证(搜索/分页/空状态)→ 确认无回归 ### Phase 3:迁移非列表页 + 关怀模式(~1.5天) - 首页、详情页、表单页等迁移为 PageShell + ContentCard - 扩展 elder-mode.scss 结构化 Token 覆写 - doctor 端页面首次获得关怀模式支持 - 全量页面关怀模式验证 ### Phase 4:清理旧代码 + 文档(~0.5天) - 删除各页面不再使用的手写样式(.search-bar, .xxx-card, .pagination 等) - 清理未使用的 mixins(card 等) - 精简 elder-mode.scss 为纯页面级特殊覆写 - 编写组件使用文档 --- ## 9. 预期效果 | 指标 | 改造前 | 改造后 | |------|--------|--------| | 页面模板代码 | ~120 行/页 | ~35 行/页 | | 卡片样式定义 | 119 处分散 | 1 处 ContentCard | | 搜索栏实现 | 4 处重写 | 1 个 SearchSection | | 分页器体系 | 2 种混用 | 1 个 PaginationBar | | 状态标签实现 | 3 种方式 | 1 个 StatusTag | | 关怀模式覆盖 | 仅患者端 TabBar | 100%(含 doctor 端) | | 新功能 UI 开发 | 从零手写 | 组装组件 | --- ## 10. 验证方式 每个迁移阶段完成后执行: - **视觉对比** — 截图对比改造前后,确保一致 - **功能验证** — 搜索、分页、空状态、错误状态均正常 - **关怀模式** — 切换后全量页面自适应无异常 - **构建通过** — `pnpm build` 无报错 - **真机预览** — DevTools 或真机预览验证触摸反馈和交互