名称
简介
React-Grid-Layout 是一个网格布局系统,具有响应性并支持断点(breakpoints)。断点布局可以由用户提供或自动生成。
RGL 仅支持 React,不支持 jQuery。
示图
安装
使用npm安装 React-Grid-Layout:
npm install react-grid-layout
样式表:
/node_modules/react-grid-layout/css/styles.css
/node_modules/react-resizable/css/styles.css
基本用法
下面的示例将生成一个包含三个项目的网格,其中:
1. 用户将无法拖动或调整项目大小 a
2. b 将被限制为最小宽度为 2 个网格块和最大宽度为 4 个网格块
3. 用户将能够自由拖动和调整项目大小 c
import GridLayout from 'react-grid-layout';
class MyFirstGrid extends React.Component {
render() {
// layout is an array of objects, see the demo for more complete usage const layout = [
{i: 'a', x: 0, y: 0, w: 1, h: 2, static: true},
{i: 'b', x: 1, y: 0, w: 3, h: 2, minW: 2, maxW: 4},
{i: 'c', x: 4, y: 0, w: 1, h: 2}
];
return (
<GridLayout className="layout" layout={layout} cols={12} rowHeight={30} width={1200}>
<div key="a">a</div>
<div key="b">b</div>
<div key="c">c</div>
</GridLayout>
)
}
}
可以选择直接在子项上设置布局属性:
import GridLayout from 'react-grid-layout';
class MyFirstGrid extends React.Component {
render() {
return (
<GridLayout className="layout" cols={12} rowHeight={30} width={1200}>
<div key="a" data-grid={{x: 0, y: 0, w: 1, h: 2, static: true}}>a</div>
<div key="b" data-grid={{x: 1, y: 0, w: 3, h: 2, minW: 2, maxW: 4}}>b</div>
<div key="c" data-grid={{x: 4, y: 0, w: 1, h: 2}}>c</div>
</GridLayout>
)
}
}
响应式用法
import { Responsive as ResponsiveGridLayout }
from 'react-grid-layout';
class MyResponsiveGrid extends React.Component {
render() {
// {lg: layout1, md: layout2, ...}
const layouts = getLayoutsFromSomewhere();
return (
<ResponsiveGridLayout className="layout" layouts={layouts} breakpoints={{lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0}} cols={{lg: 12, md: 10, sm: 6, xs: 4, xxs: 2}}>
<div key="1">1</div>
<div key="2">2</div>
<div key="3">3</div>
</ResponsiveGridLayout>
)
}
}
计算网格宽度
<ResponsiveReactGridLayout>和<ReactGridLayout>采取width来计算拖动事件位置。在简单的情况下,WidthProvider可以使用HOC在初始化和窗口调整大小事件时自动确定宽度。
import { Responsive, WidthProvider } from 'react-grid-layout';
const ResponsiveGridLayout = WidthProvider(Responsive);
class MyResponsiveGrid extends React.Component {
render() {
// {lg: layout1, md: layout2, ...}
var layouts = getLayoutsFromSomewhere();
return (
<ResponsiveGridLayout className="layout" layouts={layouts} breakpoints={{lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0}} cols={{lg: 12, md: 10, sm: 6, xs: 4, xxs: 2}}>
<div key="1">1</div>
<div key="2">2</div>
<div key="3">3</div>
</ResponsiveGridLayout>
)
}
}
Grid Layout Props
// 除使用 <WidthProvider>情况外必填
width: number,
// 如果为 true,容器高度自适应内容
autoSize: ?boolean = true,
//布局中的列数。
cols: ?number = 12,
// 取消拖拽时的css选择器
draggableCancel: ?string = '',
// 拖拽时的css选择器
draggableHandle: ?string = '',
// 紧凑排列类型
compactType: ?('vertical' | 'horizontal') = 'vertical';
// 布局,格式为数组对象,例如:
// {x: number, y: number, w: number, h: number}
// 布局中的索引必须与每个项目组件上使用的键匹配。
// 如果您选择使用自定义键,则可以在布局中指定该键
// 数组对象,如下所示:
// {i: string, x: number, y: number, w: number, h: number}
//如果父组件没有设置layout,则需要在子组件设置 data-grid
layout: ?array = null,
// [x, y] 的margin值
margin: ?[number, number] = [10, 10],
// [x, y] 的padding值
containerPadding: ?[number, number] = margin,
// 行高,可根据 breakpoints 改变
rowHeight: ?number = 150,
// 放置元素的配置。放置元素是一个从外部拖动某个元素时会出现的虚拟元素。
// i - 元素的id
// w - 元素的宽
// h - 元素的高
droppingItem?: { i: string, w: number, h: number }
// 是否可拖拽
isDraggable: ?boolean = true,
//是否可重置大小
isResizable: ?boolean = true,
//是否可设置边界
isBounded: ?boolean = false,
// 使用 CSS3 translate() 替换position 的top/left ,可提升大约6倍性能
useCSSTransforms: ?boolean = true,
//如果 ResponsiveReactGridLayout 或 ReactGridLayout 的父节点具有 "transform: scale(n)" 属性,应该设置缩放系数以避免拖动时出现渲染伪影。
transformScale: ?number = 1,
//是否允许重叠
allowOverlap: ?boolean = false,
//如果为 true,则网格项在被拖动时不会改变位置
preventCollision: ?boolean = false,
// 如果为true, 带有`draggable={true}`属性的放置元素可被放置在网格上
//注意:如果使用 Firefox,应该添加
// `onDragStart={e => e.dataTransfer.setData('text/plain', ' ')}` 属性
// 连同 `draggable={true}` 否则此功能将无法正常工作。
// Firefox 需要 onDragStart 属性来进行拖动初始化
// https://bugzilla.mozilla.org/show_bug.cgi?id=568313
isDroppable: ?boolean = false,
// 重置大小时的操作位置,默认右下
// 可选值:
// 's' - South handle (bottom-center)
// 'w' - West handle (left-center)
// 'e' - East handle (right-center)
// 'n' - North handle (top-center)
// 'sw' - Southwest handle (bottom-left)
// 'nw' - Northwest handle (top-left)
// 'se' - Southeast handle (bottom-right)
// 'ne' - Northeast handle (top-right)
resizeHandles: ?Array<'s' | 'w' | 'e' | 'n' | 'sw' | 'nw' | 'se' | 'ne'> = ['se'],
// 自定义重置大小图标
resizeHandle?: ReactElement<any> | ((resizeHandleAxis: ResizeHandleAxis, ref: ReactRef<HTMLElement>) => ReactElement<any>),
// 布局变化回调
onLayoutChange: (layout: Layout) => void,
// 下面的所有回调都有签名(layout、oldItem、newItem、placeholder、e、element)。
// 'start' 和 'stop' 回调为 'placeholder' 传递 `undefined`。
type ItemCallback = (layout: Layout, oldItem: LayoutItem, newItem: LayoutItem, placeholder: LayoutItem, e: MouseEvent, element: HTMLElement) => void,
// 拖拽开始回调
onDragStart: ItemCallback,
// 拖拽中回调
onDrag: ItemCallback,
// 拖拽停止回调
onDragStop: ItemCallback,
// 开始重置大小回调
onResizeStart: ItemCallback,
// 重置大小中的回调
onResize: ItemCallback,
// 重置大小结束回调
onResizeStop: ItemCallback,
// 当元素从外部放入网格时的回调。
onDrop: (layout: Layout, item: ?LayoutItem, e: Event) => void,
// 当一个元素从外面拖过网格时调用, 此回调应返回一个对象以动态更改 dropItem大小
onDropDragOver: (e: DragOverEvent) => ?({|w?: number, h?: number|} | false),
// 可以使用它来代替常规 ref 和已弃用的 `ReactDOM.findDOMNode()` 函数
innerRef: ?React.Ref<"div">,
Responsive Grid Layout Props
// Breakpoint名称是任意的,但是必须在cols 和 layouts 对象中匹配。
breakpoints: ?Object = {lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0},
// 列数
cols: ?Object = {lg: 12, md: 10, sm: 6, xs: 4, xxs: 2},
//[x,y]的margin
margin: [number, number] | {[breakpoint: $Keys<breakpoints>]: [number, number]},
// [x,y]的padding
containerPadding: [number, number] | {[breakpoint: $Keys<breakpoints>]: [number, number]},
// 布局配置
layouts: {[key: $Keys<breakpoints>]: Layout},
// breakpoint发生变更时的回调
onBreakpointChange: (newBreakpoint: string, newCols: number) => void,
// 布局发生变更时的回调
onLayoutChange: (currentLayout: Layout, allLayouts: {[key: $Keys<breakpoints>]: Layout}) => void,
// 宽度改变时的回调,可以根据需要修改布局。
onWidthChange: (containerWidth: number, margin: [number, number], cols: number, containerPadding: [number, number]) => void;
Grid Item Props
{
// 组件id
i: string,
// 以下单位为网格,不是px
x: number,
y: number,
w: number,
h: number,
minW: ?number = 0,
maxW: ?number = Infinity,
minH: ?number = 0,
maxH: ?number = Infinity,
// 如果为 true,则等于 `isDraggable: false, isResizable: false`。
static: ?boolean = false,
// 如果为 false,则不可拖动。覆盖 `static`.
isDraggable: ?boolean = true,
// 如果为 false,则不可重置大小。覆盖 `static`.
isResizable: ?boolean = true,
// 默认情况下,调整大小图标仅显示在右下(东南)角。
// 请注意,从顶部或左侧调整大小通常不直观。
resizeHandles?: ?Array<'s' | 'w' | 'e' | 'n' | 'sw' | 'nw' | 'se' | 'ne'> = ['se']
//如果为 true 且可拖动,则项目将仅在网格内移动。
isBounded: ?boolean = false
}