144 lines
4.0 KiB
Markdown
144 lines
4.0 KiB
Markdown
# 菜单表格优化 - 技术共识文档
|
||
|
||
## 明确的需求描述
|
||
|
||
### 核心问题
|
||
1. **表格展开后超出页面边界** - 当前高度计算不精确
|
||
2. **整个页面变为可滚动** - 需要彻底阻止页面级别滚动
|
||
3. **高度控制不精确** - 需要动态精确计算各元素高度
|
||
|
||
### 验收标准
|
||
1. 表格展开任意层级菜单时,不会超出浏览器可视区域
|
||
2. 整个页面始终保持不可滚动状态(`overflow: hidden`)
|
||
3. 表格容器高度精确适配剩余空间
|
||
4. 表格内部滚动流畅,表头和表体同步
|
||
5. 窗口大小变化时能正确响应调整
|
||
|
||
## 技术实现方案
|
||
|
||
### 1. 精确高度计算策略
|
||
**动态计算方式**:使用DOM元素实际高度,而非硬编码数值
|
||
- 卡片头部高度:动态获取 `.el-card__header` 实际高度
|
||
- 搜索容器高度:动态获取 `.search-container` 实际高度
|
||
- 工具栏高度:动态获取 `.table-toolbar` 实际高度
|
||
- 其他边距:卡片内边距、元素间距等
|
||
|
||
**计算公式**:
|
||
```
|
||
表格容器高度 = 100vh - (卡片头部 + 搜索区域 + 工具栏 + 所有边距)
|
||
```
|
||
|
||
### 2. 页面滚动控制
|
||
**全局滚动禁用**:
|
||
- 页面根容器:`overflow: hidden`
|
||
- body标签:防止任何情况下的页面滚动
|
||
- 确保所有祖先容器都不会产生滚动
|
||
|
||
**表格内部滚动**:
|
||
- 仅在表格容器内部启用滚动
|
||
- 表头固定,表体可滚动
|
||
- 保持表头和表体的水平滚动同步
|
||
|
||
### 3. 响应式高度调整
|
||
**监听机制**:
|
||
- 窗口resize事件监听
|
||
- 表格展开/折叠状态变化监听
|
||
- DOM变化监听(MutationObserver)
|
||
|
||
**调整时机**:
|
||
- 组件挂载后
|
||
- 窗口大小变化时
|
||
- 表格展开/折叠操作后
|
||
- 搜索条件变化导致数据更新后
|
||
|
||
## 技术约束
|
||
|
||
### 兼容性要求
|
||
- Vue 3 Composition API
|
||
- Element Plus 2.10.7 表格组件
|
||
- 现有的scoped CSS架构
|
||
- TypeScript类型安全
|
||
|
||
### 性能要求
|
||
- 高度计算不能影响页面渲染性能
|
||
- 展开/折叠操作响应时间 < 100ms
|
||
- 滚动操作流畅度60fps
|
||
|
||
### 集成方案
|
||
- 保持现有组件结构不变
|
||
- 不影响现有功能(CRUD操作)
|
||
- 不修改数据流和状态管理
|
||
- CSS样式向后兼容
|
||
|
||
## 实现细节设计
|
||
|
||
### 高度计算函数
|
||
```typescript
|
||
const calculateTableHeight = (): number => {
|
||
const cardHeader = document.querySelector('.el-card__header')?.offsetHeight || 0
|
||
const searchContainer = document.querySelector('.search-container')?.offsetHeight || 0
|
||
const tableToolbar = document.querySelector('.table-toolbar')?.offsetHeight || 0
|
||
const cardPadding = 40 // 卡片内边距
|
||
const margins = 20 // 其他边距
|
||
|
||
return window.innerHeight - (cardHeader + searchContainer + tableToolbar + cardPadding + margins)
|
||
}
|
||
```
|
||
|
||
### 响应式监听机制
|
||
```typescript
|
||
const setupResponsiveHeight = () => {
|
||
const resizeObserver = new ResizeObserver(() => updateTableHeight())
|
||
resizeObserver.observe(document.body)
|
||
|
||
window.addEventListener('resize', updateTableHeight)
|
||
|
||
return () => {
|
||
resizeObserver.disconnect()
|
||
window.removeEventListener('resize', updateTableHeight)
|
||
}
|
||
}
|
||
```
|
||
|
||
### CSS样式调整
|
||
```css
|
||
/* 页面级别滚动禁用 */
|
||
body, html {
|
||
overflow: hidden !important;
|
||
}
|
||
|
||
/* 动态高度表格容器 */
|
||
.table-container {
|
||
height: var(--table-height);
|
||
max-height: var(--table-height);
|
||
overflow: hidden;
|
||
}
|
||
|
||
/* 表格内部滚动区域 */
|
||
.el-table__body-wrapper {
|
||
height: calc(var(--table-height) - 40px); /* 减去表头高度 */
|
||
overflow-y: auto;
|
||
overflow-x: auto;
|
||
}
|
||
```
|
||
|
||
## 风险评估
|
||
|
||
### 潜在风险
|
||
1. **浏览器兼容性**:CSS calc()和CSS变量在旧浏览器支持
|
||
2. **性能影响**:频繁的DOM查询和高度计算
|
||
3. **边际情况**:极小窗口或极大菜单层级
|
||
|
||
### 缓解策略
|
||
1. 使用现代浏览器特性检测
|
||
2. 防抖动处理高度计算
|
||
3. 设置最小和最大高度限制
|
||
|
||
## 测试计划
|
||
|
||
### 测试场景
|
||
1. **基础功能**:正常菜单展开/折叠
|
||
2. **边界情况**:极大菜单树、极小窗口
|
||
3. **响应式**:窗口大小变化
|
||
4. **交互性**:搜索、编辑操作
|
||
5. **兼容性**:不同浏览器和屏幕分辨率 |