image.png

resizeHandles文档

x: 组件在x轴坐标
y: 组件在y轴坐标
w: 组件宽度
h: 组件高度
i: 组件key值

addItem

  1. const addItem = {
  2. x: (widgets.length * 4) % 12, // x
  3. y: Infinity, // puts it at the bottom
  4. w: 4, // w 占据多少列
  5. h: 2, // height = 2 * rowHeight 100 = 200
  6. i: String(Date.now()), // 必须是 String
  7. resizeHandles: ['s', 'w', 'e', 'n', 'sw', 'nw', 'se', 'ne'], // ['se']
  8. // isResizable: false, // 禁止缩放
  9. // isDraggable: false, // 禁止拖拽
  10. // isDroppable: true, // default, false
  11. // isBounded: true,
  12. };

拖拽方向

  1. // 's' - South handle (bottom-center)
  2. // 'w' - West handle (left-center)
  3. // 'e' - East handle (right-center)
  4. // 'n' - North handle (top-center)
  5. // 'sw' - Southwest handle (bottom-left)
  6. // 'nw' - Northwest handle (top-left)
  7. // 'se' - Southeast handle (bottom-right)
  8. // 'ne' - Northeast handle (top-right)
  9. resizeHandles: ?Array<'s' | 'w' | 'e' | 'n' | 'sw' | 'nw' | 'se' | 'ne'> = ['se']

image.png

WithResponsive

  1. import React, { useState } from 'react';
  2. import { Layout, Button } from 'antd';
  3. import { WidthProvider, Responsive } from 'react-grid-layout';
  4. import './react-grid-layout.less';
  5. const ResponsiveReactGridLayout = WidthProvider(Responsive);
  6. const INIT_STATE = {
  7. className: 'layout',
  8. // 响应式布局划分成几列
  9. cols: { lg: 12, md: 12, sm: 6, xs: 4, xxs: 1 },
  10. // 响应式布局中组件的行高
  11. rowHeight: 100, // 默认 150px
  12. layouts: {},
  13. margin: [24, 24], // 卡片之间的x, y间距,默认 10px
  14. // isResizable: false,
  15. // 布局响应式断点
  16. // breakpoints: { lg: 1200, md: 996, sm: 768, xs: 480, xxs: 0 },
  17. };
  18. const style = {
  19. position: 'relative',
  20. width: '100%',
  21. height: '100%',
  22. backgroundColor: '#f90',
  23. marginBottom: 32,
  24. };
  25. function DragLayout() {
  26. const [state, setState] = useState(INIT_STATE);
  27. const [widgets, setWidgets] = useState([]);
  28. // 生成布局中的组件
  29. function generateDOM() {
  30. return widgets.map((item, i) => {
  31. return (
  32. // data-grid为每一个组件绑定了布局属性
  33. <div key={i} data-grid={item}>
  34. <section style={style}>
  35. <h2>{i}</h2>
  36. <span
  37. style={{ position: 'absolute', right: 8, top: 8, padding: 8 }}
  38. onClick={() => onRemove(i)}
  39. >X</span>
  40. </section>
  41. </div>
  42. );
  43. });
  44. }
  45. // 新增组件
  46. function onAdd() {
  47. const ITEM = {
  48. // 一行显示多少个卡片,组件在 x轴的坐标
  49. x: (widgets.length * 4) % 12,
  50. // 组件在 Y轴的坐标
  51. y: Infinity, // puts it at the bottom
  52. // 组件的宽度 & 高度
  53. w: 4, // w 占据多少列
  54. h: 2, // height = 2 * rowHeight 100 = 200
  55. // 组件的 key值,必须是 String
  56. i: String(Date.now()),
  57. resizeHandles: ['s', 'e', 'se'], // ['se']
  58. // isResizable: false, // 禁止缩放
  59. // isDraggable: false, // 禁止拖拽
  60. // isDroppable: true, // default, false
  61. isBounded: true,
  62. };
  63. const newData = widgets.concat({ ...ITEM });
  64. setWidgets(newData);
  65. }
  66. function onRemove(index) {
  67. const filterData = widgets.filter((_, i) => index != i);
  68. setWidgets(filterData);
  69. }
  70. // 组件发生拖拽,或放大缩小时触发
  71. function onLayoutChange(layout, layouts) {
  72. setState(prevState => ({
  73. ...prevState,
  74. layouts,
  75. }));
  76. }
  77. return (
  78. <Layout>
  79. <Layout.Header>
  80. <Button onClick={onAdd}>添加图表</Button>
  81. </Layout.Header>
  82. <div style={{ background: 'rgba(63,81,181,.3)', minHeight: 900 }}>
  83. <ResponsiveReactGridLayout
  84. {...state}
  85. onLayoutChange={onLayoutChange}
  86. >
  87. {generateDOM()}
  88. </ResponsiveReactGridLayout>
  89. </div>
  90. </Layout>
  91. );
  92. }
  93. export default DragLayout;