react-grid-layout 使用说明

本文介绍了如何使用react-grid-layout库创建一个支持拖拽和自定义的dashboard页面。通过示例代码展示了如何设置布局、响应式布局以及结合WidthProvider进行窗口大小调整。关键特性包括拖拽、重置大小、响应式布局等,适用于前端开发中的自定义面板构建。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在前端工作中,经常遇到自定义dashboard页这样的需求。其中,dashboard页可以理解为一个自定义面板,用户可以在面板上自由的拖拽,新增,删除组件。组件可以是各种echarts图形,也可是各种数据表格。通过各个组件的拖拽组合,从而让用户自定义需要的dashboard页。

react-grid-layout

一个支持自由拖拽的布局组件
react-grid-layout 地址https://www.npmjs.com/package/react-grid-layout

安装

yarn add react-grid-layout

在使用时需要引入必要的样式文件
/node_modules/react-grid-layout/css/styles.css
/node_modules/react-resizable/css/styles.css

基础用法

import GridLayout from "react-grid-layout";

class MyResponsiveGrid extends React.Component {
  render() {
  	// 布局属性
	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"
        layouts={layouts}
        cols={12}
        rowHeight={30}
        width={1200}
      >
        <div key="a">1</div>
        <div key="b">2</div>
        <div key="c">3</div>
      </GridLayout>
    );
  }
}

处理上面这种在Layout组件上设置布局属性的方式,还可以直接在子元素上设置:

import GridLayout from "react-grid-layout";

class MyResponsiveGrid 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}}">1</div>
        <div key="b" data-grid="{{x: 1, y: 0, w: 3, h: 2, minW: 2, maxW: 4}}">2</div>
        <div key="c" data-grid="{{x: 4, y: 0, w: 1, h: 2}}">3</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>
    )
  }
}

参数说明:

  • breakpoints ,设置分割点
  • cols ,设置相应宽度下的总格数
  • layout ,配置相应宽度下的布局

结合 WidthProvider

使用 WidthProvider 可以在初始化和窗口大小调整事件时自动确定宽度。

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

GridLayout Props说明

  • width,设置宽度,使用 WidthProvider 时,此属性将失效。
  • autoResize,为true时,容器的高度会自适应内容的高度
  • cols,布局列数
  • draggableCancel,取消拖动时被拖动项的类选择器的名称
  • draggableHandle,拖动时被拖动项的类选择器的名称
  • compactType,紧凑排列类型
  • layout,布局
  • margin,项与项之间的间距,单位是px
  • containerPadding,项的内边距
  • rowHeight,行高(项的默认高度,设置拖拽设置项的高度时,高度会是这个的倍数)
  • droppingItem,放置元素的配置(放置元素即是当你拖动某一项时出现的虚拟元素)
  • isDraggable,是否可拖拽
  • isResizable,是否可重置大小
  • isBounded,是否设置边界
  • useCSSTransforms,是否使用CSS 3 的translate() 来代替 position left/top(可加快渲染速度)
  • transformScale,若ResponsiveReactGridLayout 或者 ReactGridLayout的父组件具有"transform: scale(n)"这一css属性,应该设置这一比例系数以避免拖拽时出现“伪影”
  • allowOverlap
  • preventCollision,为真时,项在拖动时不会变更位置
  • isDroppable,为真时,设置了draggable={true}属性的项可以被放置入其他项
  • resizeHandles,设置重置大小的图标出现的位置,默认是在右下角
  • resizeHandle,自定义重置大小组件(即默认出现在右下角的那个小图标,可自定义)
  • onLayoutChange,布局发生变化的回调函数
  • onDragStart,某一项开始拖动的回调函数
  • onDrag,某一项拖动中的回调函数
  • onDragStop,某一项停止拖动的回调函数
  • onResizeStart,某一项开始重置大小的回调函数
  • onResize,某一项正在重置大小中的回调函数
  • onResizeStop,某一项停止重置大小的回调函数
  • onDrop,某一项所包含的内容中被放置其他元素后的回调函数
  • onDropDragOver,某一项被拖拽到container外面时的回调

Responsive Props说明

  • breakpoints ,设置响应式布局的分割点
  • cols ,设置不同区间内的布局列数
  • margin ,项与项之间边距的设置
  • containerPadding ,项的内边距的设置
  • layouts ,布局
  • onBreakpointChange ,breakpoint发生变更时的回调函数
  • onLayoutChange ,布局发生变化的回调函数
  • onWidthChange ,container宽度发生变化的回调函数
### 解决 React-grid-layout 嵌套布局项互相影响的方法 当使用 `react-grid-layout` 实现嵌套布局时,可能会遇到子网格中的项目会影响父级或其他兄弟组件的布局问题。为了防止这种情况发生,可以采取以下几种方法: #### 方法一:独立管理每个 Grid 的状态 通过为每一个 `ReactGridLayout` 定义单独的状态来控制其内部项目的排列方式,而不是共享全局配置。 ```javascript import { useState } from 'react'; import ReactGridLayout, { WidthProvider } from "react-grid-layout"; const ResponsiveGrid = WidthProvider(ReactGridLayout); function NestedLayout() { const [outerLayout, setOuterLayout] = useState([ { i: 'a', x: 0, y: 0, w: 1, h: 2 }, { i: 'b', x: 1, y: 0, w: 3, h: 2 } ]); const [innerLayoutA, setInnerLayoutA] = useState([{i:'aa',x:0,y:0,w:1,h:1}]); return ( <> <ResponsiveGrid layout={outerLayout}> {/* Outer grid item */} <div key="a"> <h3>Item A</h3> <ResponsiveGrid layout={innerLayoutA}> {/* Inner grid items */} <div key="aa">Nested Item AA</div> </ResponsiveGrid> </div> <div key="b"><h3>Item B</h3></div> </ResponsiveGrid> </> ); } ``` 这种方法确保了不同级别的网格不会因为彼此的存在而受到影响[^1]。 #### 方法二:设置静态位置属性 对于不需要动态调整大小或拖拽功能的部分,可以通过 CSS 设置固定宽度和高度,并禁用这些元素上的交互操作。 ```css .static-item { position: absolute !important; top: auto !important; left: auto !important; width: /* specific value */ !important; height: /* specific value */ !important; } /* Disable resizing and dragging */ .react-grid-item.no-dragging .static-item, .react-resizable-static { cursor: default; touch-action: none; } ``` 此策略适用于那些只需要展示而不参与任何互动行为的小部件[^2]。 #### 方法三:利用 ColWidth 和 RowHeight 属性优化间距 适当调节列宽 (`colWidth`) 和行高 (`rowHeight`) 参数可以帮助改善视觉效果并减少重叠现象的发生概率。 ```jsx <ResponsiveGrid colWidth={120} rowHeight={150}></ResponsiveGrid> ``` 合理设定这两个参数有助于创建更清晰的空间分隔线,从而降低相邻区域之间的干扰程度[^3]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值