在React中实现拖拽自由布局可以使用HTML5的拖放API。以下是一个简单的实现示例:
首先,创建一个Draggable组件,用于包装可拖拽的元素:
```javascript
import React from 'react';
const Draggable = ({ id, onDragStart, children }) => {
const handleDragStart = (event) => {
event.dataTransfer.setData('text/plain', id);
onDragStart(id);
};
return (
draggable
onDragStart={handleDragStart}
style={{ cursor: 'move' }}
>
{children}
);
};
export default Draggable;
```
然后,在父组件中创建一个容器元素,并监听拖放事件:
```javascript
import React, { useState } from 'react';
import Draggable from './Draggable';
const FreeLayout = () => {
const [draggedItem, setDraggedItem] = useState(null);
const [items, setItems] = useState([]);
const handleDrop = (event) => {
event.preventDefault();
const itemId = event.dataTransfer.getData('text/plain');
const newItem = { id: itemId, x: event.clientX, y: event.clientY };
setItems([...items, newItem]);
setDraggedItem(null);
};
const handleDragOver = (event) => {
event.preventDefault();
};
const handleDragStart = (itemId) => {
setDraggedItem(itemId);
};
return (
onDrop={handleDrop}
onDragOver={handleDragOver}
style={{ width: '500px', height: '500px', border: '1px solid black' }}
>
{items.map((item) => (
key={item.id}
style={{
position: 'absolute',
left: item.x,
top: item.y,
border: '1px solid red',
padding: '10px',
}}
>
{item.id}
))}
Item 1
Item 2
);
};
export default FreeLayout;
```
在上面的示例中,FreeLayout组件中的state用于存储已拖拽的元素的位置信息。Draggable组件用于封装可拖拽的元素,并在拖拽开始时触发回调函数。
在容器元素上监听drop和dragover事件,并在drop事件中获取拖拽的元素信息,并将其添加到state中。在拖拽元素上触发dragstart事件时,将元素的id存储在state中。
最后,根据state中的元素位置信息渲染拖拽的元素,并设置其位置为绝对定位。
这样就实现了一个简单的拖拽自由布局。你可以根据需求进行扩展和优化。