Files
EmailBill/openspec/changes/archive/2026-02-20-refactor-popup-container-component/design.md
SunCheng 6e95568906
All checks were successful
Docker Build & Deploy / Build Docker Image (push) Successful in 18s
Docker Build & Deploy / Deploy to Production (push) Successful in 6s
Docker Build & Deploy / Cleanup Dangling Images (push) Successful in 0s
Docker Build & Deploy / WeChat Notification (push) Successful in 1s
fix
2026-02-20 13:56:29 +08:00

108 lines
5.0 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
## Context
项目中已有 `PopupContainer.vue` 通用弹窗组件(位于 `Web/src/components/PopupContainer.vue`),但其样式设计与 `TransactionDetailSheet.vue` 不同:
- PopupContainer: 使用 Vant 主题变量,默认高度 80%,标准化的布局
- TransactionDetailSheet: 使用 Inter 字体16px 圆角,纯白背景(#ffffff / #18181b),更现代化的视觉风格
`TransactionDetailSheet.vue` 当前实现(位于 `Web/src/components/Transaction/TransactionDetailSheet.vue`
- 直接使用 `van-popup` + 自定义样式
- 头部:自定义标题 + 关闭按钮(`.sheet-header`
- 内容区域:金额、表单字段、分类选择器(无固定滚动容器)
- 底部操作按钮:删除、保存(`.actions-section`
- 样式特点:`borderTopLeftRadius: 16px`, Inter 字体, `#ffffff` 背景, `gap: 24px`
当前问题:头部和底部未固定,内容较多时滚动体验不佳。
## Goals / Non-Goals
**Goals:**
- 创建 `PopupContainerV2.vue` 通用组件,采用 TransactionDetailSheet 的样式风格
- 提供固定头部(标题 + 可选关闭按钮)、可滚动内容、固定底部的布局能力
- 支持暗色模式(`#18181b` 背景)
- 将 TransactionDetailSheet 重构为使用 PopupContainerV2
- 保持 TransactionDetailSheet 所有现有功能和对外 API 不变
**Non-Goals:**
- 不修改现有的 `PopupContainer.vue`v1 版本保持不变)
- 不强制项目中其他组件迁移到 v2自愿迁移
- 不改变 TransactionDetailSheet 的业务逻辑
- 不引入新的 UI 库或依赖
## Decisions
### 决策 1创建新组件 PopupContainerV2 而不是修改 PopupContainer
**选择**: 创建新的 `PopupContainerV2.vue` 组件
**理由**:
- PopupContainer 已在项目中广泛使用CategoryBillPopup 等),修改可能影响现有组件
- TransactionDetailSheet 的样式风格更现代,适合作为新版本
- v1 和 v2 可以并存,逐步迁移,降低风险
- **替代方案**: 直接修改 PopupContainer → 不采用,破坏性太大,需要验证所有使用方
### 决策 2PopupContainerV2 的样式来源
**选择**: 完全采用 TransactionDetailSheet 的样式风格
**理由**:
- TransactionDetailSheet 的样式已经过验证,用户体验良好
- Inter 字体、16px 圆角、纯白背景是现代化设计趋势
- 保持样式一致性,避免混合不同的设计语言
- **替代方案**: 混合 PopupContainer 和 TransactionDetailSheet 的样式 → 不采用,会导致样式不统一
### 决策 3PopupContainerV2 的 API 设计
**选择**: 提供 title prop、default 插槽、footer 插槽,关闭按钮默认显示
**理由**:
- title prop 简化使用,覆盖 80% 场景
- default 插槽放可滚动内容,最大灵活性
- footer 插槽放固定底部操作按钮
- 关闭按钮默认显示,符合 TransactionDetailSheet 的行为
- **替代方案**: 提供 header 插槽替代 title prop → 不采用,增加使用复杂度,大多数场景只需简单标题
### 决策 4内容区域的 padding 处理
**选择**: PopupContainerV2 的内容插槽不提供默认 padding由使用方控制
**理由**:
- TransactionDetailSheet 的不同区域有不同的 padding 需求(金额区域 16px 16px 24px表单区域 0 16px 16px
- 组件不应预设 padding保持灵活性
- 使用方可以根据内容自行调整间距
- **替代方案**: 提供统一的 padding → 不采用,会限制布局灵活性
### 决策 5TransactionDetailSheet 的迁移策略
**选择**: 完全移除原有的头部和外层布局代码,使用 PopupContainerV2 的插槽
**理由**:
- 避免代码重复,减少维护成本
- PopupContainerV2 已提供所有需要的布局能力
- 保持 TransactionDetailSheet 的职责单一(业务逻辑)
- **替代方案**: 保留部分原有代码 → 不采用,会造成样式冲突和维护混乱
## Risks / Trade-offs
### 风险 1新增 PopupContainerV2 组件增加项目复杂度
**缓解措施**:
- 在组件文件顶部添加清晰的文档注释,说明 v1 和 v2 的区别
- v2 组件设计简洁API 清晰,易于理解和使用
- 在使用 TransactionDetailSheet 时验证 v2 的稳定性后,再考虑推广到其他组件
### 风险 2样式迁移可能遗漏细节
**缓解措施**:
- 仔细对比 TransactionDetailSheet 的原有样式
- 使用 Chrome DevTools 对比重构前后的渲染效果
- 验证暗色模式的样式一致性
### 风险 3日期选择器van-datetime-picker的嵌套弹窗可能存在 z-index 冲突
**缓解措施**: van-datetime-picker 使用 `teleport="body"`,应与 PopupContainerV2 的弹窗层级独立,测试时重点验证
### Trade-off 1创建 v2 而不是统一到一个组件
**影响**: 项目中会同时存在两个弹窗组件,增加学习成本
**权衡**: 保护现有代码稳定性的收益大于维护两个组件的成本,且 v2 可以逐步替代 v1
### Trade-off 2PopupContainerV2 不提供默认 padding
**影响**: 使用方需要自行管理内容区域的间距
**权衡**: 灵活性优于便利性,避免样式冲突