不能用固定 grid-template-rows 定义全部行,因为会强制浏览器创建全部轨道,丧失按需渲染优势并引发性能问题;应让列表区域作为单个 grid 项目,由 js 动态控制内容渲染与滚动定位。

虚拟列表的外层布局不能靠 grid-template-rows 预设所有行高——那样会失去“只渲染可视区域”的意义,反而加重性能负担。
为什么不能用固定 grid-template-rows 定义全部行
虚拟列表的核心是“按需渲染”,比如 10000 条数据,实际只挂载 20 个 DOM 节点。若写 grid-template-rows: repeat(10000, 60px),浏览器会尝试生成 10000 行轨道,触发巨大计算开销,甚至卡死。
- Grid 的
repeat(N, ...)在 N 极大时,解析和重排成本线性上升 -
grid-template-rows是显式网格,必须提前声明所有轨道,违背虚拟化初衷 - 滚动定位依赖的是容器高度 + 滚动偏移,不是 Grid 轨道索引
正确做法:用 Grid 做容器骨架,内容靠 JS 动态插入
外层容器用 Grid 控制整体结构(比如侧边栏+主列表区),但列表本身不参与 Grid 行定义;它只是 Grid 中一个子项,内部由 JS 管理真实 DOM 节点。
- 外层容器设
display: grid,用grid-template-columns或grid-template-areas划分区域 - 列表区域(如
.list-area)设为单个 Grid 项目,不设grid-template-rows - 该区域内部用
position: relative+transform: translateY(...)模拟滚动,或直接用scrollTop配合offsetTop计算可见范围 - Grid 只负责“把列表框放在哪”,不负责“列表里每一项在哪”
gap 和 align-items 可以安全使用
这些属性作用于 Grid 项目之间或项目内部对齐,不触发轨道预分配,对虚拟列表友好。
-
gap: 8px可用于侧边栏与列表区之间的间距 -
align-items: start确保列表区域顶部对齐,避免因内容高度变化导致错位 - 若列表区需垂直居中(如空状态提示),可用
place-content: center,但注意它会影响子元素默认流,需配合height: 100%和明确尺寸
真正容易被忽略的是:Grid 容器的 height 必须可计算(比如 100vh 或固定像素),否则虚拟列表无法知道“可视区域多高”,也就无法判断该渲染哪几条。别指望 min-height: 100% 在无父级高度约束时生效。
前端入门到VUE实战笔记:立即使用
在学习笔记中,你将探索 前端 的入门与实战技巧!











