121 lines
4.2 KiB
Markdown
121 lines
4.2 KiB
Markdown
|
|
## Context
|
||
|
|
|
||
|
|
余额页面(BalanceView.vue)当前使用 Vant UI 库的默认组件:`van-nav-bar` 作为头部导航,`van-tabs type="card"` 作为标签页切换。而统计页面(statisticsV2)已经采用了更现代的自定义设计:使用 `DateSelectHeader` 组件作为头部,`TimePeriodTabs` 作为分段控制器。
|
||
|
|
|
||
|
|
现有代码结构:
|
||
|
|
- `Web/src/views/BalanceView.vue` - 主要页面组件
|
||
|
|
- `Web/src/components/DateSelectHeader.vue` - 统计页面头部组件(包含日期切换)
|
||
|
|
- `Web/src/components/TimePeriodTabs.vue` - 分段控制器组件(周/月/年)
|
||
|
|
- `Web/src/assets/theme.css` - CSS 变量定义
|
||
|
|
|
||
|
|
余额页面的三个标签页(账单/邮件/消息)需要保留的特定功能:
|
||
|
|
- 邮件页:右上角"立即同步"按钮
|
||
|
|
- 消息页:右上角"标记全部已读"图标
|
||
|
|
|
||
|
|
## Goals / Non-Goals
|
||
|
|
|
||
|
|
**Goals:**
|
||
|
|
- 统一余额页面和统计页面的视觉风格
|
||
|
|
- 使用分段控制器(segmented control)替代卡片式标签
|
||
|
|
- 创建简化版头部布局(仅文字标题,无日期切换)
|
||
|
|
- 保留所有现有功能(同步按钮、标记已读图标等)
|
||
|
|
- 复用现有样式变量,确保主题切换(亮色/暗色)正常工作
|
||
|
|
|
||
|
|
**Non-Goals:**
|
||
|
|
- 不修改统计页面的任何代码
|
||
|
|
- 不改变余额页面的业务逻辑
|
||
|
|
- 不创建新的通用组件(直接在 BalanceView.vue 内实现)
|
||
|
|
- 不调整底层数据加载逻辑
|
||
|
|
|
||
|
|
## Decisions
|
||
|
|
|
||
|
|
### 决策 1: 组件复用策略
|
||
|
|
|
||
|
|
**选择**: 直接在 BalanceView.vue 内实现简化版头部和标签页,不复用 DateSelectHeader 或 TimePeriodTabs
|
||
|
|
|
||
|
|
**理由**:
|
||
|
|
- DateSelectHeader 包含日期切换逻辑,余额页面不需要
|
||
|
|
- TimePeriodTabs 是三个固定选项(周/月/年),余额页面需要不同的三个选项(账单/邮件/消息)
|
||
|
|
- 直接实现可以更灵活地保留右上角操作按钮(同步、标记已读)
|
||
|
|
- 代码量较小,不值得抽象为通用组件
|
||
|
|
|
||
|
|
**备选方案**:
|
||
|
|
- ❌ 修改 TimePeriodTabs 支持自定义选项 → 增加组件复杂度,影响统计页面
|
||
|
|
- ❌ 创建新的通用组件 BalanceTabsComponent → 过度设计,只有一个使用场景
|
||
|
|
|
||
|
|
### 决策 2: 头部布局结构
|
||
|
|
|
||
|
|
**选择**: 采用 `<header>` 标签 + 标题文字 + 右侧操作按钮的扁平布局
|
||
|
|
|
||
|
|
**理由**:
|
||
|
|
- 与 DateSelectHeader 的视觉效果一致
|
||
|
|
- 灵活支持动态显示右侧按钮(根据当前标签页)
|
||
|
|
- 无需复杂的嵌套结构
|
||
|
|
|
||
|
|
**样式规范**:
|
||
|
|
- 使用 `var(--font-2xl)` 作为标题字号
|
||
|
|
- 使用 `var(--text-primary)` 作为标题颜色
|
||
|
|
- 透明背景:`background: transparent`
|
||
|
|
- 内边距:`padding: 8px 24px`
|
||
|
|
|
||
|
|
### 决策 3: 分段控制器实现
|
||
|
|
|
||
|
|
**选择**: 复制 TimePeriodTabs 的 CSS 结构,修改选项数据
|
||
|
|
|
||
|
|
**理由**:
|
||
|
|
- 确保视觉效果 100% 一致
|
||
|
|
- 避免重复造轮子
|
||
|
|
- 样式已经过亮色/暗色主题测试
|
||
|
|
|
||
|
|
**关键样式**:
|
||
|
|
```scss
|
||
|
|
.segmented-control {
|
||
|
|
display: flex;
|
||
|
|
background: var(--segmented-bg);
|
||
|
|
border-radius: 8px;
|
||
|
|
padding: 4px;
|
||
|
|
gap: 4px;
|
||
|
|
height: 40px;
|
||
|
|
}
|
||
|
|
|
||
|
|
.tab-item.active {
|
||
|
|
background: var(--segmented-active-bg);
|
||
|
|
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.12);
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
### 决策 4: 右侧操作按钮布局
|
||
|
|
|
||
|
|
**选择**: 使用 `v-if` 条件渲染,根据 `tabActive` 动态显示不同按钮
|
||
|
|
|
||
|
|
**理由**:
|
||
|
|
- 简洁明了,易于维护
|
||
|
|
- 与现有代码风格一致
|
||
|
|
- 性能开销可忽略
|
||
|
|
|
||
|
|
**实现**:
|
||
|
|
```vue
|
||
|
|
<van-button v-if="tabActive === 'email'" @click="...">立即同步</van-button>
|
||
|
|
<van-icon v-if="tabActive === 'message'" name="passed" @click="..."/>
|
||
|
|
```
|
||
|
|
|
||
|
|
## Risks / Trade-offs
|
||
|
|
|
||
|
|
### 风险 1: CSS 变量未定义
|
||
|
|
**风险**: `theme.css` 中可能缺少 `--segmented-bg` 或 `--segmented-active-bg` 变量
|
||
|
|
**缓解**: 实施前检查变量定义,必要时添加兼容值
|
||
|
|
|
||
|
|
### 风险 2: 移动端触控区域
|
||
|
|
**风险**: 自定义按钮的触控区域可能不如 Vant 组件优化
|
||
|
|
**缓解**: 确保按钮最小高度 44px,添加 `-webkit-tap-highlight-color: transparent`
|
||
|
|
|
||
|
|
### 权衡 1: 代码复用 vs 灵活性
|
||
|
|
**权衡**: 选择在 BalanceView.vue 内实现而非抽象组件
|
||
|
|
**影响**: 如果未来其他页面需要类似布局,需要重复代码
|
||
|
|
**判断**: 可接受 - 当前只有一个使用场景,过早抽象会增加维护成本
|
||
|
|
|
||
|
|
### 权衡 2: 视觉一致性 vs 功能保留
|
||
|
|
**权衡**: 需要在统一样式的同时保留特定功能按钮
|
||
|
|
**影响**: 头部布局不能完全照搬 DateSelectHeader
|
||
|
|
**判断**: 功能优先 - 同步和标记已读是核心功能,不能牺牲
|