在前端工作中,经常遇到自定义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>
);
}
}
width
,设置宽度,使用 WidthProvider
时,此属性将失效。autoResize
,为true时,容器的高度会自适应内容的高度cols
,布局列数draggableCancel
,取消拖动时被拖动项的类选择器的名称draggableHandle
,拖动时被拖动项的类选择器的名称compactType
,紧凑排列类型layout
,布局margin
,项与项之间的间距,单位是pxcontainerPadding
,项的内边距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外面时的回调breakpoints
,设置响应式布局的分割点cols
,设置不同区间内的布局列数margin
,项与项之间边距的设置containerPadding
,项的内边距的设置layouts
,布局onBreakpointChange
,breakpoint发生变更时的回调函数onLayoutChange
,布局发生变化的回调函数onWidthChange
,container宽度发生变化的回调函数