我想拥有一个网格,该网格将始终具有例如3行和3列。 现在假设这些是我的网格项目
<div className="myClass" key="1">1</div>
<div className="myClass" key="2">2</div>
<div className="myClass" key="3">3</div>
<div className="myClass" key="4">4</div>
<div className="myClass" key="5">5</div>
<div className="myClass" key="6">6</div>
<div className="myClass" key="7">7</div>
<div className="myClass" key="8">8</div>
<div className="myClass" key="9">9</div>
假设所有项目的宽度和高度均相同,并且无法调整大小。
如果我将9垂直拖动到6,也就是项目会交换它们的位置。 但是,如果我将9水平拖动到8上,则8项将下降到新行,而9将代替8,而9的前一个位置将为空。 是否可以使项目在水平拖动过程中也只是交换位置,而不是创建新行?
答案 0 :(得分:0)
所以我将onLayoutChange
添加到了ReactGridLayout
阅读代码注释以获取更多详细信息。
private onLayoutChange = (layout: any) => {
const fixedLayout = this.fixLayout(layout)
this.setState({
layout: fixedLayout
})
}
/**
* The `react-grid-layout` lib is not swapping items during horizontal dragover
* Rather it moves the items into a new row
* Since we need a static 3x3 row, let's fix that
*/
private fixLayout = (layout: any) => {
// `y` is calculated by `h` in the layout object, since `h` is 20
// first row will be 0, second 20, third 40
const maxY = 40
// when an item goes to a new row, there is an empty column in the maxY row
// so here we find which columns exist
// tslint:disable-next-line:max-line-length
const maxRowXs = layout.map((item: any) => item.y === maxY ? item.x : null).filter((value: any) => value !== null)
// xs or cols, we only have 3 cols
const xs = [0,1,2]
// find the missing col
// tslint:disable-next-line:max-line-length
const missingX = xs.find((value: any) => maxRowXs.every((maxRowX: number) => maxRowX !== value))
// bring the item from the new row into maxY row
// and place it in the missing column
const fixedLayout = layout.map((item: any) => {
if (item.y > maxY) {
return {
...item,
y: maxY,
x: missingX
}
}
return item
})
return fixedLayout
}
答案 1 :(得分:0)
Hayk Safaryan's Answer 很棒,解决了这个确切的问题,但是我发现添加“maxRows={3}”修复了答案中的一个错误,您可以堆叠 4,因为 ui 在布局数据之前更新。
我的代码:
import { useState } from "react";
import GridLayout from "react-grid-layout";
const Drag = () => {
// layout is an array of objects, see the demo for more complete usage
const [layout,setLayout] = useState([
{ i: "a", x: 0, y: 0, w: 1, h: 1, isResizable: false, },
{ i: "b", x: 1, y: 0, w: 1, h: 1, isResizable: false, },
{ i: "c", x: 2, y: 0, w: 1, h: 1, isResizable: false, },
{ i: "d", x: 0, y: 1, w: 1, h: 1, isResizable: false, },
{ i: "e", x: 1, y: 1, w: 1, h: 1, isResizable: false, },
{ i: "f", x: 2, y: 1, w: 1, h: 1, isResizable: false, },
{ i: "g", x: 0, y: 2, w: 1, h: 1, isResizable: false, },
{ i: "h", x: 1, y: 2, w: 1, h: 1, isResizable: false, },
{ i: "i", x: 2, y: 2, w: 1, h: 1, isResizable: false, },
]);
return (
<GridLayout
className="layout"
layout={layout}
cols={3}
rowHeight={100}
width={1500}
onLayoutChange={e=>setLayout(fixLayout(e))}
maxRows={3}
>
<div key="a" style={{ background: "grey" }}>
a
</div>
<div key="b" style={{ background: "grey" }}>
b
</div>
<div key="c" style={{ background: "grey" }}>
c
</div>
<div key="d" style={{ background: "grey" }}>
d
</div>
<div key="e" style={{ background: "grey" }}>
e
</div>
<div key="f" style={{ background: "grey" }}>
f
</div>
<div key="g" style={{ background: "grey" }}>
g
</div>
<div key="h" style={{ background: "grey" }}>
h
</div>
<div key="i" style={{ background: "grey" }}>
i
</div>
</GridLayout>
);
};
export default Drag;
/**
* The `react-grid-layout` lib is not swapping items during horizontal dragover
* Rather it moves the items into a new row
* Since we need a static 3x3 row, let's fix that
*/
const fixLayout = (layout) => {
// `y` is calculated by `h` in the layout object, since `h` is 20
// first row will be 0, second 20, third 40
const maxY = 2
// when an item goes to a new row, there is an empty column in the maxY row
// so here we find which columns exist
// tslint:disable-next-line:max-line-length
const maxRowXs = layout.map((item) => item.y === maxY ? item.x : null).filter((value) => value !== null)
// xs or cols, we only have 3 cols
const xs = [0,1,2]
// find the missing col
// tslint:disable-next-line:max-line-length
const missingX = xs.find((value) => maxRowXs.every((maxRowX) => maxRowX !== value))
// bring the item from the new row into maxY row
// and place it in the missing column
const fixedLayout = layout.map((item) => {
if (item.y > maxY) {
const fixedItem = {
...item,
y: maxY,
x: missingX
}
return fixedItem
}
return item
})
return fixedLayout
}