如何实现按行填充的Material-UI Masonry类型Image List
实现按行填充的Masonry类型Image List
Material-UI的Image List组件默认填充规则:
- 无
variant属性或使用非masonry变体时,图片按行优先填充(先填满一行再换行) - 设置
variant="masonry"时,图片按列优先填充(先填满一列再换列)
默认行优先填充示例(无variant):
<ImageList sx={{ width: 600 }} cols={3}> {itemData.map((item) => ( <ImageListItem key={item.img}> <img srcSet={`${item.img}?w=164&h=164&fit=crop&auto=format&dpr=2 2x`} src={`${item.img}?w=164&h=164&fit=crop&auto=format`} /> </ImageListItem> ))} </ImageList>
默认列优先填充的Masonry示例:
<ImageList sx={{ width: 600 }} cols={3} variant="masonry"> {itemData.map((item) => ( <ImageListItem key={item.img}> <img srcSet={`${item.img}?w=164&h=164&fit=crop&auto=format&dpr=2 2x`} src={`${item.img}?w=164&h=164&fit=crop&auto=format`} /> </ImageListItem> ))} </ImageList>
解决方案:重排数据顺序 + 保留Masonry布局
Masonry变体的列优先逻辑是组件内置的,要实现行优先的Masonry布局,核心是先把数据按行优先逻辑重排,再传给Masonry组件,让组件的列填充逻辑最终呈现行优先的视觉效果。
1. 编写数据重排函数
根据列数cols,将原数组先按行分组,再按列拼接:
// 按行优先重排数据,适配Masonry的列填充逻辑 const reorderForRowFirstMasonry = (data, cols) => { // 先按行分组:[[行1项1,行1项2,行1项3], [行2项1,行2项2,行2项3], ...] const rows = []; for (let i = 0; i < data.length; i += cols) { rows.push(data.slice(i, i + cols)); } // 按列拼接:[行1项1,行2项1,...行n项1, 行1项2,行2项2,...行n项2, ...] const reordered = []; for (let col = 0; col < cols; col++) { for (const row of rows) { if (row[col]) { reordered.push(row[col]); } } } return reordered; };
2. 在组件中使用重排后的数据
将原itemData处理后,传入variant="masonry"的Image List:
const cols = 3; const reorderedItemData = reorderForRowFirstMasonry(itemData, cols); <ImageList sx={{ width: 600 }} cols={cols} variant="masonry"> {reorderedItemData.map((item) => ( <ImageListItem key={item.img}> <img srcSet={`${item.img}?w=164&h=164&fit=crop&auto=format&dpr=2 2x`} src={`${item.img}?w=164&h=164&fit=crop&auto=format`} alt={item.title} /> </ImageListItem> ))} </ImageList>
原理说明
Masonry组件会按列依次填充传入的数组,我们先把数据按行分组再按列提取,组件填充列时,每一列的内容对应原数据每一行的同位置项,最终视觉上呈现行优先排列,同时保留Masonry的瀑布流布局特性。
内容的提问来源于stack exchange,提问作者gaitat
相关产品推荐
相关产品推荐

