react-grid-layout:可拖拽缩放网格布局插件

名称

react-grid-layout

简介

    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

    }

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 202,802评论 5 476
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,109评论 2 379
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 149,683评论 0 335
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,458评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,452评论 5 364
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,505评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,901评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,550评论 0 256
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,763评论 1 296
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,556评论 2 319
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,629评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,330评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,898评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,897评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,140评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,807评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,339评论 2 342

推荐阅读更多精彩内容