daily-share
daily-share copied to clipboard
react-beautiful-dnd 初探(2020-11-4)
简单的使用方式
- hooks 方式实现
import React, { useState } from 'react'
import { DragDropContext, Droppable, Draggable, DropResult, DraggingStyle } from "react-beautiful-dnd"
import { createUseStyles } from 'react-jss'
const styles = createUseStyles({
box: {
width: '100%',
height: '100px',
}
})
export const Demo: React.FC = () => {
const classes = styles()
const getItems = (count: number) => {
return Array.from({ length: count }, (v, k) => k).map(k => ({
id: `item-${k}`,
content: `item ${k}`
}))
}
const [items, setItems] = useState(getItems(4))
const onDragEnd = (res: DropResult) => {
if (!res.destination) {
return
}
const item = reorder(items, res.source.index, res.destination.index)
setItems([...item])
}
const reorder = (list: any, startIndex: number, endIndex: number) => {
console.log(endIndex, startIndex)
const result = list
const [removed] = result.splice(startIndex, 1)
result.splice(endIndex, 0, removed)
return result
}
// 样式相关
const getListStyle = (isDraggingOver: boolean) => ({
background: isDraggingOver ? "lightblue" : "lightgrey"
})
// 样式相关
const getItemStyle = (isDragging: boolean, draggableStyle: any) => ({
userSelect: "none",
// change background colour if dragging
background: isDragging ? "lightgreen" : "grey",
// styles we need to apply on draggables
...draggableStyle
})
return (
<DragDropContext onDragEnd={onDragEnd}>
<Droppable droppableId="droppable">
{(provided, snapshot) => (
<div
{...provided.droppableProps}
ref={provided.innerRef}
style={{
height: '600px',
width: '100%',
...getListStyle(snapshot.isDraggingOver)
}}
>
{
items.map( (item, index) => (
<Draggable key={item.id} draggableId={item.id} index={index}>
{(provided1, snapshot1) => (
<div
ref={provided1.innerRef}
{...provided1.draggableProps}
{...provided1.dragHandleProps}
className={ classes. box}
style={{ ...getItemStyle(snapshot1.isDragging, provided1.draggableProps.style), animation: snapshot1.dropAnimation}}
>{ item.content }
</div>
)}
</Draggable>
))
}
</div>
)}
</Droppable>
</DragDropContext>
)
}
实战组件封装
import React, { useState } from 'react'
import { DragDropContext, Droppable, Draggable, DropResult, DraggingStyle } from "react-beautiful-dnd"
import { createUseStyles } from 'react-jss'
import { Iconfont } from '../icon-font/icon-font'
import { Row } from '../layout/base'
const styles = createUseStyles({
item: {
position: 'relative',
display: 'flex',
alignItems: 'center',
justifyContent: 'space-between',
height: '50px',
backgroundColor: '#fff',
"&:after": {
position: 'absolute',
bottom: 0,
width: 'calc(100% - 20px)',
content: "''",
margin: '0 10px',
height: '1px',
backgroundColor: 'rgba(0, 0, 0, 0.05)'
}
},
left: {
display: 'flex',
alignItems: 'center',
flex: 1,
height: '50px',
paddingLeft: '10px',
flexShrink: 0
},
right: {
position: 'relative',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
width: '60px',
height: '50px',
"&:after": {
left: 0,
position: 'absolute',
content: "''",
width: '1px',
height: '20px',
backgroundColor: 'rgba(0, 0, 0, 0.1)'
}
}
})
interface IProps {
lists?: Array<{
[x: string]: any,
id: number,
title: string
}>
}
export const DragDrop: React.FC<IProps> = (props) => {
const classes = styles()
const { lists } = props
const [items, setItems] = useState(lists)
const onDragEnd = (res: DropResult) => {
if (!res.destination) {
return
}
const item = reorder(items, res.source.index, res.destination.index)
setItems([...item])
}
const reorder = (list: any, startIndex: number, endIndex: number) => {
console.log(endIndex, startIndex)
const result = list
const [removed] = result.splice(startIndex, 1)
result.splice(endIndex, 0, removed)
return result
}
// 样式相关
const getListStyle = (isDraggingOver: boolean) => ({
background: '#fff'
})
// 样式相关
const getItemStyle = (isDragging: boolean, draggableStyle: any) => ({
userSelect: "none",
boxShadow: isDragging ? '1px 3px 5px rgb(0 0 0 / 10%)' : '',
...draggableStyle
})
return (
<DragDropContext onDragEnd={onDragEnd}>
<Droppable droppableId="droppable">
{(provided, snapshot) => (
<div
{...provided.droppableProps}
ref={provided.innerRef}
style={{
width: '100%',
...getListStyle(snapshot.isDraggingOver)
}}
>
{
items && items.map( (item, index) => (
<Draggable
key={item.id} draggableId={item.title} index={index}
>
{(provided1, snapshot1) => (
<div
ref={provided1.innerRef}
className={ classes.item }
{...provided1.draggableProps}
style={{ ...getItemStyle(snapshot1.isDragging, provided1.draggableProps.style), animation: snapshot1.dropAnimation}}
>
<Row className={ classes.left }>
<span>{ item.title }</span>
</Row>
<div
className={ classes.right }
{...provided1.dragHandleProps}
>
<Iconfont name='icontuodong' size='25'></Iconfont>
</div>
</div>
)}
</Draggable>
))
}
</div>
)}
</Droppable>
</DragDropContext>
)
}
DragDrop.defaultProps = {
lists: [
{
id: 1,
title: '列表1'
},
{
id: 2,
title: '列表2'
},
{
id: 3,
title: '列表3'
}
]
}