You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Grid布局大量单元格无法自动正确放置,Vue代码出现重叠问题求助

Why Do Grid Cells Overlap With a Large List in Vue?

Great question—let's break down exactly what's causing this overlap and how to fix it.

The Root Cause: Duplicate key Values in v-for

The biggest issue here is your choice of :key="item.height" for the v-for loop. Vue requires that key values are unique identifiers for each list item—they help Vue's virtual DOM track which elements have changed, been added, or been removed.

Since you're generating random height values (between 10 and 310), when your list gets large enough, it's almost guaranteed that two items will end up with the same height (even floating-point values can collide, or Math.ceil(item.height) will produce duplicates). When Vue sees duplicate keys, it reuses existing DOM elements instead of creating new ones for the new items. This breaks CSS Grid's layout logic: Grid relies on having a consistent set of DOM elements in the correct order to calculate track positions and span sizes. Reusing elements confuses Grid, leading to overlapping cells.

Quick Fix: Use a Unique Key

The simplest fix is to replace the key with a value that's guaranteed to be unique for each item. You have two easy options here:

  1. Use the loop index (perfect for this dynamic, non-persistent list):

    <div class="item" v-for="(item, index) in list" :key="index" :style="{ 'grid-row': `span ${Math.ceil(item.height)}` }">
      {{index+1}}: {{item.height}}
    </div>
    
  2. Generate a unique ID for each item (better if you ever need to modify or reorder the list later):
    Update your list generation to include a unique ID:

    data() {
      return {
        list: Array.from({ length: 10 }).map((_, idx) => {
          return { 
            id: idx + 1, // Unique identifier
            height: Math.random() * 300 + 10 
          };
        })
      };
    }
    

    Then use the ID as the key:

    <div class="item" v-for="(item, index) in list" :key="item.id" :style="{ 'grid-row': `span ${Math.ceil(item.height)}` }">
      {{index+1}}: {{item.height}}
    </div>
    

Minor Tweak to Strengthen the Grid Layout

While not the main cause of overlap, adding height: 100% to your .item class ensures each cell fully fills the Grid track it's assigned to, eliminating any potential rendering inconsistencies:

.item {
  border: 2px solid rgb(226, 199, 77);
  height: 100%;
}

Why It Worked With Small Lists

When your list was short, the random height values were unlikely to repeat. With unique keys, Vue created a new DOM element for each item, and Grid could calculate the layout correctly. As the list grew, duplicate keys became inevitable, triggering the DOM reuse that broke the layout.

内容的提问来源于stack exchange,提问作者Alexerx

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.08 17:42:34