Home

Awesome

STRML/react-grid-layout explain translate-svg

<!-- [![size-img]][size] -->

「 React-Grid-Layout:网格布局(grid layout)系统,但专为 React 服务 」

中文 | english


校对 ✅

<!-- doc-templite START generated --> <!-- repo = 'STRML/react-grid-layout' --> <!-- commit = '80873c88b32755bd0ae028df20edc955c2c55d3e' --> <!-- time = '2019-02-02' -->
翻译的原文与日期最新更新更多
commit⏰ 2019-02-02last中文翻译
<!-- doc-templite END generated -->

贡献

欢迎 👏 勘误/校对/更新贡献 😊 具体贡献请看

生活

If help, buy me coffee —— 营养跟不上了,给我来瓶营养快线吧! 💰


React grid layout

travis build CDNJS npm package npm downloads

React-Grid-Layout 是一个非常类似Packery要么Gridster的网格布局(grid layout)系统,但专为 React 服务。

与那些系统不同,它具有响应性,并支持断点(breakpoints)。断点布局可由用户提供或自动生成。

RGL(React-Grid-Layout 的缩写) 是 React-only,且不需要 jQuery。

BitMEX UI

GIF 来自BitMEX.com的实际演示。

[Demo|Changelog|CodeSandbox 可编辑 DEmo]

目录

<!-- START doctoc generated TOC please keep comment here to allow auto update --> <!-- DON'T EDIT THIS SECTION, INSTEAD RE-RUN doctoc TO UPDATE --> <!-- END doctoc generated TOC please keep comment here to allow auto update -->

演示

  1. 展示
  2. 基本
  3. 没有 拖放/调整大小 (仅是 布局)
  4. 乱排版式,自动更正
  5. 在子级上,定义的布局
  6. 静态元素
  7. 添加/删除元素
  8. 将布局保存到本地存储
  9. 将响应布局保存到本地存储(LocalStorage)
  10. 最小和最大宽度/高度
  11. 动态的,最小和最大宽度/高度
  12. 无垂直紧凑(自由移动)
  13. 防止碰撞
  14. 错误案例
  15. 工具箱

使用 React-Grid-Layout 的项

知道别的吗?创建个 PR,让我知道!

特征

版本兼容性
> = 0.11.3React 0.14 和 v15
> = 0.10.0React 0.14
0.8。- 0.9.2React 0.13
<0.8React 0.12

安装

安装 React-Grid-Layout package,使用npm

npm install react-grid-layout

在您的应用程序中,包含以下样式表:

/node_modules/react-grid-layout/css/styles.css
/node_modules/react-resizable/css/styles.css

用法

像任何其他组件一样,使用 ReactGridLayout。以下示例将生成一个包含三个项的网格,其中:

import GridLayout from 'react-grid-layout';

class MyFirstGrid extends React.Component {
  render() {
    // layout(布局) 为 一个具有多对象数组, 你可以看看Demo展示集合,里面有更完整的用法
    var 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>
    );
  }
}

您也可以直接在子(children)项上,设置布局属性:

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

不使用 Browserify / Webpack 的用法

可用于<script>标签的模块,包括在这里。它使用 UMD shim,并排除React,因此必须通过 RequireJS 或提供window.React,才能在你应用中工作。

响应模式的用法

应用 RGL 的响应模式,请使用<ResponsiveReactGridLayout>元素:

import {Responsive as ResponsiveGridLayout} from 'react-grid-layout';

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

在响应模式下,您应该通过layouts属性提供至少一个断点(breakpoints)。

使用layouts时,最好提供尽可能多的断点,尤其是最大的断点。如果最大值已提供,RGL 将尝试插入其余部分。

你还需要提供一个width,在使用<ResponsiveReactGridLayout>时,建议你使用 HOCWidthProvider,按照以下说明。

目前,无法通过个别项的data-grid属性,提供响应映射,但快到了。

提供网格宽度

<ResponsiveReactGridLayout><ReactGridLayout>两者,都采取width,计算 drag 事件的位置。在简单的情况下,一个 HOCWidthProvider可在初始化和窗口 resize 事件时,自动确定宽度。

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

这使您可以轻松更换WidthProvider,为您自己的 Provider HOC,如果您需要更复杂的逻辑的话。

WidthProvider接受一个 Props,measureBeforeMount。如果为trueWidthProvider将在安装(mount) children 之前,测量容器的宽度。如果您想完全消除 应用程序/组件 mount 上的,任何调整大小动画,请使用此选项。

有一个更复杂的布局?WidthProvider 是很简单的,并且只听监听'resize'的窗口事件。如果您需要更多功能和灵活性,请尝试使用SizeMe React HOC,作为 WidthProvider 的替代品。

网格布局 Props

RGL 支持以下属性(请参阅,最终来源):

//
// 基础 props
//

// 设置 初始 width 在服务器端.
// 必须的,除非使用 HOC <WidthProvider> 或 类似的
width: number,

// 如果为 true ,容器高度会膨胀,并紧凑以适应内容物。
autoSize: ?boolean = true,

// 此布局中的列数。
cols: ?number = 12,

// 一个CSS选择器, 不能拖放
// 例如: draggableCancel:'.MyNonDraggableAreaClassName'
// 若你忘了加上 `.` ,那么就不会工作
draggableCancel: ?string = '',

// 一个CSS选择器, 能拖放处理.
// 例如: draggableHandle:'.MyDragHandleClassName'
// 若你忘了加上 `.` ,那么就不会工作
draggableHandle: ?string = '',

// 如果是 true, 这个布局 垂直紧凑
verticalCompact: ?boolean = true,

// 紧凑类型.
compactType: ?('vertical' | 'horizontal') = 'vertical';

// Layout 是由一定格式的对象所组成的数组:
// {x: number, y: number, w: number, h: number}
// layout的索引,必须匹配,用在每个组件项上的 key。
// 如果 你选择使用自定义的 keys, 你可以指定为,在 layout
// 数组中对象的 keys ,像这样( i 就是 key ):
// {i: string, x: number, y: number, w: number, h: number}
layout: ?array = null, // 如果 不提供, 那使用 children 的 data-grid props

// [x, y]项与项之间的 Margin ,px 单位.
margin: ?[number, number] = [10, 10],

// 容器 [x, y] 里面的 Padding ,px 单位.
containerPadding: ?[number, number] = margin,

// Rows 具有一个 静态 height, 但
// 如果你喜欢的话,你可以基于 breakpoints,改变它.
rowHeight: ?number = 150,

//
// 标志
//
isDraggable: ?boolean = true,
isResizable: ?boolean = true,
// 使用 CSS3 translate() 代替 position top/left.
// 会让性能提升 6 倍
useCSSTransforms: ?boolean = true,

// 若 true,当其被拖(放)起来时,网格项不会改变 position。
preventCollision: ?boolean = false;

//
// 回调函数
//

// 因为 回调函数, 所以你可以保存 layout.
// 在每次 drag 或 resize stop事件之后,用 (currentLayout) 回调。
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

响应式网格布局 Props

可以使用响应式网格布局。它支持上面的所有 Props,除了layout。新属性和更改是:

// {name: pxVal}, 例如: {lg: 1200, md: 996, sm: 768, xs: 480}
// 断点名称是任意的,但必须在 cols和 layouts 对象中,匹配。
breakpoints: ?Object = {lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0},
#
// cols 的 #。这是一个断点 -> cols 的 map,例如:{lg: 12, md: 10, ...}
cols: ?Object = {lg: 12, md: 10, sm: 6, xs: 4, xxs: 2},

// 布局是将断点,映射到布局的对象。
// 例如: {lg: Layout, md: Layout, ...}
layouts: {[key: $Keys<breakpoints>]: Layout}

//
// 回调
//

// 使用断点和新 # 列回调
onBreakpointChange: (newBreakpoint: string, newCols: number) => void,

// 回调,以便保存布局。
// 所有布局都由断点,打上key。
onLayoutChange: (currentLayout: Layout, allLayouts: {[key: $Keys<breakpoints>]: Layout}) => void,

// 当宽度更改时回调,以便根据需要,修改布局。
onWidthChange: (containerWidth: number, margin: [number, number], cols: number, containerPadding: [number, number]) => void;

网格项 Props

RGL 的网格项或布局项支持以下属性。初始化网格时,构建一个布局数组(如上面的第一个示例中,所示),或者将此对象附加到,每个子元素的data-grid属性(如第二个示例中,所示)。

请注意,如果提供的网格项不完整(缺少其中一个)x, y, w, or h),将抛出错误,以便更正您的布局。

如果没有为网格项,提供属性,则将生成宽度和高度为1的网格项。

您可以为每个层级,设置最小值和最大值。这是为了调整大小;如果禁用调整大小,它当然没有效果。如果您的最小值和最大值,重叠不正确,或者您的初始尺寸超出范围,则会引发错误。

<GridItem>直接定义的任何属性,优先于全局设置选项。例如,如果布局具有isDraggable: false属性,但网格项 Props 有 isDraggable: true,该项将是可拖动的。

{

  // 一个 字符串,对应组件的 key
  i: string,

  // 在 grid 单元中的所有, 不是 像素(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, 则不能拖放 draggable. 被 `static` 覆盖.
  isDraggable: ?boolean = true,
  // 如果为 false, 则不能调整大小 resizable. 被 `static` 覆盖.
  isResizable: ?boolean = true
}

帮助

如果您有功能请求,请将其添加为问题或提出拉取请求。

如果您有错误报告,请在CodeSandbox重现该错误,帮助我们轻松识别它。

TODO 清单