使用React、Js、Mui实现拖拽功能
能够左右拖拽,并且右侧可以拖拽排序
使用到的库@dnd-kit/core、@dnd-kit/sortable、'@dnd-kit/utilities
安装
npm install @dnd-kit/core @dnd-kit/sortable @dnd-kit/utilities
主页面DragContainer
import React, { useState } from 'react';
import { Stack, Box } from '@mui/material';
import LeftArea from './leftArea';
import RightArea from './rightArea';
const DragContainer = () => {
const [leftItems, setLeftItems] = useState([
{ id: '1', name: 'Item 1' },
{ id: '2', name: 'Item 2' },
{ id: '3', name: 'Item 3' },
{ id: '4', name: 'Item 4' },
{ id: '5', name: 'Item 5' },
{ id: '6', name: 'Item 6' },
{ id: '7', name: 'Item 7' },
{ id: '8', name: 'Item 8' },
{ id: '9', name: 'Item 9' },
{ id: '10', name: 'Item 10' },
{ id: '11', name: 'Item 11' },
{ id: '12', name: 'Item 12' },
]);
const [rightItems, setRightItems] = useState([]);
const handleDragStart = (e, item) => {
e.dataTransfer.setData('application/json', JSON.stringify(item));
};
const handleDrop = (e) => {
const data = e.dataTransfer.getData('application/json');
const item = JSON.parse(data);
setRightItems((prev) => [...prev, item]);
// setLeftItems((prev) => prev.filter((i) => i.id !== item.id));
};
const disabledItems = rightItems.map((item) => item.id);
return (
<Stack direction="row" spacing={2}>
<LeftArea
items={leftItems}
onDragStart={handleDragStart}
disabledItems={disabledItems}
/>
<Box
style={{ flex: 1 }}
onDragOver={(e) => e.preventDefault()}
onDrop={handleDrop}
>
<RightArea items={rightItems} setItems={setRightItems} />
</Box>
</Stack>
);
};
export default DragContainer;
左侧区域LeftArea
import React from 'react';
import { Paper, Stack, Typography } from '@mui/material';
const LeftArea = ({ items, onDragStart, disabledItems }) => {
return (
<Paper
elevation={3}
style={{
padding: '16px',
minWidth: '200px',
width: '30%',
height: '800px',
overflow: 'auto',
}}
>
<Typography variant="h6">左侧区域</Typography>
<Stack spacing={1}>
{items.map((item) => (
<div
key={item.id}
draggable={!disabledItems.includes(item.id)}
onDragStart={(e) =>
!disabledItems.includes(item.id) && onDragStart(e, item)
}
style={{
padding: '8px',
backgroundColor: disabledItems.includes(item.id)
? '#e0e0e0'
: '#e3f2fd',
borderRadius: '4px',
textAlign: 'center',
cursor: disabledItems.includes(item.id) ? 'not-allowed' : 'grab',
opacity: disabledItems.includes(item.id) ? 0.5 : 1,
}}
>
{item.name}
</div>
))}
</Stack>
</Paper>
);
};
export default LeftArea;
右侧区域 RightArea
import React from 'react';
import { DndContext, closestCenter } from '@dnd-kit/core';
import {
SortableContext,
arrayMove,
verticalListSortingStrategy,
} from '@dnd-kit/sortable';
import { Paper, Stack, Typography } from '@mui/material';
import DraggableItem from './draggableItem';
const RightArea = ({ items, setItems }) => {
const handleDragEnd = (event) => {
const { active, over } = event;
if (active.id !== over.id) {
setItems((prevItems) => {
const oldIndex = prevItems.findIndex((item) => item.id === active.id);
const newIndex = prevItems.findIndex((item) => item.id === over.id);
return arrayMove(prevItems, oldIndex, newIndex);
});
}
};
return (
<Paper
elevation={3}
style={{
padding: '16px',
minWidth: '200px',
width: '50%',
height: '800px',
overflow: 'auto',
}}
>
<Typography variant="h6">右侧区域</Typography>
<DndContext collisionDetection={closestCenter} onDragEnd={handleDragEnd}>
<SortableContext items={items} strategy={verticalListSortingStrategy}>
<Stack spacing={1}>
{items.map((item) => (
<DraggableItem
key={item.id}
id={item.id}
name={item.name}
disabled={false}
/>
))}
</Stack>
</SortableContext>
</DndContext>
</Paper>
);
};
export default RightArea;
拖拽项 DraggableItem
import React from 'react';
import { useSortable } from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
const DraggableItem = ({ id, name, disabled }) => {
const { attributes, listeners, setNodeRef, transform, transition } =
useSortable({ id });
const style = {
transform: CSS.Transform.toString(transform),
transition,
padding: '8px',
margin: '4px 0',
backgroundColor: '#f0f0f0',
borderRadius: '4px',
textAlign: 'center',
cursor: disabled ? 'not-allowed' : 'grab',
opacity: disabled ? 0.5 : 1,
};
return (
<div
ref={setNodeRef}
style={style}
{...attributes}
{...(disabled ? {} : listeners)}
>
{name}
</div>
);
};
export default DraggableItem;
标签:const,name,Item,Js,React,item,import,Mui,id
From: https://www.cnblogs.com/sxliu414/p/18584009