vue 3虚拟表格展开行需动态高度缓存与增量更新:用positiondata数组存每行top、height、isexpanded,首次渲染后测量更新;展开时仅改当前行height并重算后续top;滚动用二分查找定位可视区;placeholder高度为末行top+height。

Vue 3 中处理带展开行(expandable row)的表格虚拟化,核心难点在于:**每行真实高度不可预知,且展开/收起会动态改变整行高度,进而影响后续所有行的累计偏移量**。固定高度方案完全失效,必须采用“动态高度 + 高度缓存 + 增量更新”的组合策略。
用 positionData 缓存每行的累计位置和真实高度
不能只存单个 item 的高度,而要维护一个 positionData 数组,每一项包含:top(该行顶部距列表顶部的距离)、height(该行当前真实渲染高度)、isExpanded(是否展开)。初始时用预估高度填充,首次渲染后立即测量并更新。
- 展开某行时,只更新该行的
height,并重新计算它之后所有行的top - 使用
nextTick确保 DOM 渲染完成后再读取clientHeight - 为避免频繁重排,可对
positionData的更新做防抖或节流
滚动时用二分查找快速定位可视区域起始索引
因为每行高度不同,无法用 scrollTop / itemHeight 直接算起始 index。必须基于 positionData 中的 top 数组做二分查找:
- 输入:当前
scrollTop - 目标:找到最后一个
top 的索引,其下一项即为可视区首行 - 返回
startIndex和endIndex(根据视口高度反向累加高度得到)
撑开滚动容器需动态响应展开状态
幽灵容器(placeholder)的高度不再是 预估高度 × 总行数,而是 positionData[positionData.length - 1].top + 最后一行高度。每次有行展开/收起,都必须:
- 触发
positionData重算 - 同步更新 placeholder 的
height样式 - 必要时手动调整
scrollTop防止滚动错位(例如展开后原位置变空)
表格结构适配:避免 el-table 默认样式干扰
若基于 Element Plus 的 el-table 改造,注意三点:
- 禁用
el-table自带的height和max-height,由虚拟容器控制整体高度 - 展开行内容需包裹在绝对定位的
.cell内,用top定位,而非依赖表格默认流式布局 - 自定义
expand-row插槽时,确保内部元素能被正确测量(避免display: none或未渲染)
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!










