基于vue3.0和element-plus的组件库
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

121 lines
4.5 KiB

# Plan: Viewport Resize Handling for list-table-v2
## 1. Problem Analysis
### Current State
- The `list-table-v2` component uses a probe row technique to dynamically measure row height when `rowHeight` is NOT explicitly set (dynamic height mode)
- The `measureProbeRow` function (lines 217-231) already exists and correctly:
- Clears `estimatedRowHeight.value` before re-measuring
- Uses TWO `requestAnimationFrame` calls after `nextTick` to let el-table-v2 fully settle
- Measures the probe row's `offsetHeight`
### Problem
- When the viewport width changes, column widths may adjust (due to `flexGrow: 1` in `tableColumns` computed)
- This can cause row heights to change, but currently there is no trigger to re-measure
- Without re-measuring, the `estimatedRowHeight` may become inaccurate, causing layout issues
### Constraints (from previous attempts)
1. ResizeObserver on container caused errors in component setup - AVOID
2. Must use TWO `requestAnimationFrame` calls after `nextTick` for proper el-table-v2 settlement
3. Must clear `estimatedRowHeight` before re-measuring for el-table-v2 to recalculate properly
---
## 2. Implementation Approach
### Strategy
Add a debounced window resize event listener that:
1. Checks if dynamic height mode is active (`shouldUseProbeRow`)
2. Calls the existing `measureProbeRow` function
3. Cleans up properly on component unmount
### Why Window Resize Instead of ResizeObserver
- `el-auto-resizer` already handles container size changes internally
- Window resize is the correct trigger because column widths change based on viewport width (via `flexGrow`)
- ResizeObserver on container caused setup errors in previous attempts
### Debounce Strategy
- Use lodash's `debounce` (already imported as `lodash-es`)
- Debounce delay: ~200-300ms to avoid excessive recalculations during active resize
- The debounced function will be created with `onMounted` and cleaned up with `onUnmounted`
---
## 3. Code Changes Needed
### File: `/home/hechang27/Documents/sprt/noob-components/packages/base/data/list-table-v2.vue`
#### Import Additions (line 53)
```typescript
import { ref, computed, watch, h, onMounted, onUpdated, onUnmounted, useSlots, renderSlot, nextTick } from "vue";
```
#### New State Variable
After line 66 (`const estimatedRowHeight = ref<number | undefined>(undefined);`):
```typescript
// Debounced resize handler for re-measuring probe row
const debouncedResizeHandler = ref<() => void>();
```
#### New Lifecycle Hooks
After line 214 (after the existing `watch` block):
```typescript
// Setup resize listener on mount
onMounted(() => {
// Create debounced handler
debouncedResizeHandler.value = lodash.debounce(() => {
// Only re-measure in dynamic height mode
if (shouldUseProbeRow.value) {
measureProbeRow();
}
}, 250); // 250ms debounce delay
// Attach window resize listener
window.addEventListener('resize', debouncedResizeHandler.value);
});
// Cleanup on unmount
onUnmounted(() => {
if (debouncedResizeHandler.value) {
window.removeEventListener('resize', debouncedResizeHandler.value);
debouncedResizeHandler.value.cancel(); // Cancel any pending debounce calls
}
});
```
---
## 4. Verification Steps
### Manual Testing
1. Open a page using `list-table-v2` without explicit `rowHeight` prop
2. Open browser DevTools and inspect a row element to see its height
3. Resize the browser window (change width)
4. Verify that:
- No console errors occur during resize
- The row height is recalculated correctly after resize settles
- The table layout remains correct after resize
### Edge Cases to Verify
1. **Rapid resize**: Resize window quickly back and forth - should not cause errors or excessive measurements
2. **Minimum width**: Table should handle minimum width gracefully without breaking
3. **No explicit rowHeight**: Verify resize handling is NOT active when `rowHeight` IS set (fixed height mode)
4. **Unmount cleanup**: Navigate away from the page and verify no memory leaks or hanging listeners
### Code Review Checklist
- [ ] `onUnmounted` is imported and used
- [ ] Debounced handler is properly cancelled on unmount
- [ ] `shouldUseProbeRow.value` check prevents unnecessary calls in fixed-height mode
- [ ] Two RAF frames are used in `measureProbeRow` (existing pattern preserved)
- [ ] `estimatedRowHeight` is cleared before re-measuring (existing pattern preserved)
---
## 5. Dependencies
- lodash-es debounce (already imported)
- Vue lifecycle hooks (already available)
No new dependencies required.