react-grid-layout

1,818 阅读1分钟

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>
    );
  }


推荐

react-grid-layout核心功能实现

欢迎关注我的前端自检清单,我和你一起成长