在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中的元素位置信息渲染拖拽的元素,并設置其位置為絕對定位。
這樣就實現了一個簡單的拖拽自由布局。你可以根據需求進行擴展和優化。