1、是什么?
react-grid-layout是基于react的网格布局系统
特性
- 可拖拽
- 可调整大小
- 静态部件(不可拖拽、调整大小)
- 拖拽和调整大小时进行边界检查
- 增减部件时避免重建栅格
- 可序列化和还原的布局
- 自动化 RTL 支持
- 响应式
用法如下
import React from 'react';
import GridLayout from 'react-grid-layout';
export default class App extends React.PureComponent {
render() {
// layout is an array of objects
// static 表示不可拖动和缩放
// key是必须的
const layout = [
{ i: 'a', x: 0, y: 1, w: 1, h: 1, static: true },
{ i: 'b', x: 1, y: 0, w: 3, h: 2 },
{ i: 'c', x: 4, y: 0, w: 1, h: 2 },
];
return (
<GridLayout layout={layout} width={1200}>
<div key="a">a</div>
<div key="b">b</div>
<div key="c">c</div>
</GridLayout>
);
}
}
2、实现分析
2.1 grid-layout
- style={positive:relative}
- render 合并样式和类名、绑定拖拽事件、渲染children React.Children.map(this.props.children,child=>this.processGridItem(child) )}
- synchronizeLayoutWithChildren 计算layout
- onDragStop、onResizeStop 改变layout
- getLayoutItem 获取layout
- correctBounds 边界控制
- getFirstCollision collides碰撞检测
- compact 布局空间压缩
- containerHeight 容器高度计算
2.2 grid-item
- style={width:w,height:h,position:absolute,transform:translate(x,y) ;}
- render 被DraggableCore、Resizeable标签包裹
- getPositionParams() 获取props里面布局列数、行高
- pos = calcGridItemPositon()计算布局相关参数
- createStyle(pos) 设置位置,分为setTransform和setTopLeft两种方式
2.3 Resizeable
import { Resizeable } from 'react-resizable';
function mixinResizable(child,position,isResizable) {
const {
cols,
x,
minW,
minH,
maxW,
maxH,
transformScale,
resizeHandles,
resizeHandle
} = this.props;
const positionParams = this.getPositionParams();
// 最大宽度
const maxWidth = calcGridItemPosition(positionParams, 0, 0, cols - x, 0)
.width;
// 计算最小网格布局和最大网格布局和对应的容器大小
const mins = calcGridItemPosition(positionParams, 0, 0, minW, minH);
const maxes = calcGridItemPosition(positionParams, 0, 0, maxW, maxH);
const minConstraints = [mins.width, mins.height];
const maxConstraints = [
Math.min(maxes.width, maxWidth),
Math.min(maxes.height, Infinity)
];
return (
<Resizable
draggableOpts={{
disabled: !isResizable,
}}
className={isResizable ? undefined : "react-resizable-hide"}
width={position.width}
height={position.height}
minConstraints={minConstraints}
maxConstraints={maxConstraints}
onResizeStop={this.onResizeStop}
onResizeStart={this.onResizeStart}
onResize={this.onResize}
transformScale={transformScale}
resizeHandles={resizeHandles}
handle={resizeHandle}
>
{child}
</Resizable>
);
}
2.4 DraggableCore
import { DraggableCore } from 'react-draggable';
function mixinDraggable(child, isDraggable) {
// 下面这些拖拽相关的回调函数用于接收额外的位置信息,计算布局
return (
<DraggableCore
disabled={!isDraggable}
onStart={this.onDragStart}
onDrag={this.onDrag}
onStop={this.onDragStop}
handle={this.props.handle}
cancel={`.react-resizable-handle${ this.props.cancel ?
`,${ this.props.cancel}` : ''}`}
scale={this.props.transformScale}
nodeRef={this.elementRef}
>
{child}
</DraggableCore>
);
}
推荐
欢迎关注我的前端自检清单,我和你一起成长