網(wǎng)站首頁 編程語言 正文
dnd文檔
html 拖拽排序
import React, { useState, useRef } from 'react';
import { cloneDeep } from 'lodash';
import styles from './index.less';
const defaultList = [
{
id: 1,
name: '11',
},
{
id: 2,
name: '22',
},
];
export default ({ children = '', arr = [] }) => {
const [list, setList] = useState([...defaultList]);
const startRef = useRef(null);
const changePosition = (dragIndex, hoverIndex) => {
const data = cloneDeep(list);
const temp = data[dragIndex];
// 交換位置
data[dragIndex] = data[hoverIndex];
data[hoverIndex] = temp;
setList(data);
};
const onDragStart = index => {
// console.log('onDragStart', index);
startRef.current = index;
};
const onDragEnd = (e, index) => {
e.preventDefault();
};
const onDragOver = (e, index) => {
e.preventDefault();
};
const onDragEnter = (e, hoverIndex) => {
e.preventDefault();
if (startRef.current === hoverIndex) {
return;
}
startRef.current = hoverIndex; // 將當(dāng)前當(dāng)前移動(dòng)到Box的index賦值給當(dāng)前拖動(dòng)的box,不然會(huì)出現(xiàn)兩個(gè)盒子瘋狂抖動(dòng)!
changePosition(startRef.current, hoverIndex);
// console.log('onDragEnd', hoverIndex, '排序');
};
return (
<div className={styles.list_container}>
{list.map((item, index) => {
return (
<div
className={styles.list_item}
draggable
key={item?.id}
onDragStart={$event => onDragStart(index)}
onDragEnd={$event => onDragEnd($event, index)}
onDragEnter={$event => onDragEnter($event, index)}
onDragOver={$event => onDragOver($event, index)}
>
{item.name}
{/* {children} */}
</div>
);
})}
</div>
);
};
拖拽組件封裝
import React, { useRef } from 'react';
import { useDrop, useDrag } from 'react-dnd';
import styles from './index.less';
// 拖拽排序
export default ({ id = '', index = '', changePosition = () => {}, className = {}, children, rowKey = '' }) => {
const ref = useRef(null);
// 因?yàn)闆]有定義收集函數(shù),所以返回值數(shù)組第一項(xiàng)不要
const [, drop] = useDrop({
accept: 'DragDropBox', // 只對(duì)useDrag的type的值為DragDropBox時(shí)才做出反應(yīng)
hover: (item, monitor) => {
// 這里用節(jié)流可能會(huì)導(dǎo)致拖動(dòng)排序不靈敏
if (!ref.current) return;
const dragIndex = item.index;
const hoverIndex = index;
if (dragIndex === hoverIndex) return; // 如果回到自己的坑,那就什么都不做
changePosition(dragIndex, hoverIndex); // 調(diào)用傳入的方法完成交換
item.index = hoverIndex; // 將當(dāng)前當(dāng)前移動(dòng)到Box的index賦值給當(dāng)前拖動(dòng)的box,不然會(huì)出現(xiàn)兩個(gè)盒子瘋狂抖動(dòng)!
},
});
const [{ isDragging }, drag] = useDrag({
item: {
type: 'DragDropBox',
id,
index,
},
collect: monitor => ({
isDragging: monitor.isDragging(), // css樣式需要
}),
});
return (
// ref 這樣處理可以使得這個(gè)組件既可以被拖動(dòng)也可以接受拖動(dòng)
<div ref={drag(drop(ref))} style={{ opacity: isDragging ? 0.5 : 1 }} className={className.dragBox}>
<span key={rowKey} className={styles.reviewer}>
{children}
</span>
</div>
);
};
使用組件
import React from 'react';
import { DndProvider } from 'react-dnd';
import { useSelector } from 'umi';
import { cloneDeep } from 'lodash';
import HTML5Backend from 'react-dnd-html5-backend';
import ReactDndDragSort from '@/components/ReactDndDragSort';
import styles from './index.less';
export default ({ currentModel, dispatch }) => {
const { reviewerList = [] } = useSelector(state => state[currentModel]);
const changePosition = (dragIndex, hoverIndex) => {
const data = cloneDeep(reviewerList);
const temp = data[dragIndex];
// 交換位置
data[dragIndex] = data[hoverIndex];
data[hoverIndex] = temp;
// setBoxList(data);
dispatch({
type: `${currentModel}/overrideStateProps`,
payload: {
reviewerList: data,
},
});
};
return (
<>
<div className={styles.reviewerContainer}>
<DndProvider backend={HTML5Backend}>
{reviewerList?.length ? (
<div style={{ display: 'flex' }}>
{reviewerList.map((item, index) => {
return (
<ReactDndDragSort
rowKey={item?.id}
index={index}
id={item?.id}
changePosition={changePosition}
>
<span key={item?.id} className={styles.reviewer}>
<div className={styles.reviewerImg}>
<span
className="saas saas-failure1"
onClick={() => {
const listFilter = reviewerList.filter(
(_, itemIndex) => itemIndex !== index,
);
dispatch({
type: `${currentModel}/overrideStateProps`,
payload: {
reviewerList: listFilter,
},
});
}}
/>
</div>
<div className={styles.reviewerTxt}>{item.name}</div>
</span>
</ReactDndDragSort>
);
})}
</div>
) : null}
</DndProvider>
</div>
</>
);
};
ts 版本
import React, { useRef } from "react";
import { useDrop, useDrag } from "react-dnd";
import "./index.less";
// dnd拖拽排序
export default (props: any) => {
const {
id = "",
index = "",
changePosition = () => {},
className = "",
children,
rowKey = "",
} = props;
const ref: any = useRef(null);
// 因?yàn)闆]有定義收集函數(shù),所以返回值數(shù)組第一項(xiàng)不要
const [, drop] = useDrop({
accept: "DragDropBox", // 只對(duì)useDrag的type的值為DragDropBox時(shí)才做出反應(yīng)
hover: (item: any, monitor: any) => {
// 這里用節(jié)流可能會(huì)導(dǎo)致拖動(dòng)排序不靈敏
if (!ref.current) return;
const dragIndex = item.index;
const hoverIndex = index;
if (dragIndex === hoverIndex) return; // 如果回到自己的坑,那就什么都不做
changePosition(dragIndex, hoverIndex); // 調(diào)用傳入的方法完成交換
item.index = hoverIndex; // 將當(dāng)前當(dāng)前移動(dòng)到Box的index賦值給當(dāng)前拖動(dòng)的box,不然會(huì)出現(xiàn)兩個(gè)盒子瘋狂抖動(dòng)!
},
});
const [{ isDragging }, drag] = useDrag(() => ({
type: "DragDropBox",
item: { id, type: "DragDropBox", index },
collect: (monitor) => ({
isDragging: monitor.isDragging(), // css樣式需要
}),
}));
const changeRef = drag(drop(ref));
return (
// ref 這樣處理可以使得這個(gè)組件既可以被拖動(dòng)也可以接受拖動(dòng)
<div
//@ts-ignore
ref={changeRef}
style={{ opacity: isDragging ? 0.5 : 1 }}
className="dragBox"
>
<span key={rowKey} className={className}>
{children}
</span>
</div>
);
};
ts使用
import React, { useState } from "react";
import { DndProvider } from "react-dnd";
import { useSelector } from "react-redux";
//@ts-ignore
import { cloneDeep } from "lodash";
import { HTML5Backend } from "react-dnd-html5-backend";
import ReactDndDragSort from "@/components/ReactDndDragSort";
import "./index.less";
console.log("HTML5Backend", HTML5Backend);
export default () => {
const dList = [
{
id: 99,
name: "組1",
},
{
id: 22,
name: "組2",
},
];
const [reviewerList, setReviewerList] = useState(dList);
const changePosition = (dragIndex: any, hoverIndex: any) => {
const data = cloneDeep(reviewerList);
const temp = data[dragIndex];
// 交換位置
data[dragIndex] = data[hoverIndex];
data[hoverIndex] = temp;
console.log("交換完成---", data);
setReviewerList(data);
};
return (
<>
<div className="reviewerContainer">
<DndProvider backend={HTML5Backend}>
{reviewerList?.length ? (
<div>
{reviewerList.map((item: any, index: any) => {
return (
<ReactDndDragSort
rowKey={item?.id}
index={index}
id={item?.id}
changePosition={changePosition}
>
<div key={item?.id} className="reviewer">
<div className="reviewerTxt">{item.name}</div>
</div>
</ReactDndDragSort>
);
})}
</div>
) : null}
</DndProvider>
</div>
</>
);
};
原文鏈接:https://blog.csdn.net/waillyer/article/details/121522841
相關(guān)推薦
- 2022-04-28 python實(shí)現(xiàn)線性回歸的示例代碼_python
- 2022-02-05 Numpy中不同維度數(shù)組之間的計(jì)算
- 2022-09-29 Shell之function函數(shù)的定義及調(diào)用示例_linux shell
- 2022-07-13 仿 OriginOS 無清理項(xiàng)動(dòng)畫
- 2022-09-05 Linux系統(tǒng)下創(chuàng)建守護(hù)進(jìn)程
- 2022-08-25 .net?core中高效的動(dòng)態(tài)內(nèi)存管理方案_實(shí)用技巧
- 2022-12-22 一文帶你深入了解Go語言中切片的奧秘_Golang
- 2022-06-17 Android?SearchView搜索控件使用方法詳解_Android
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡(jiǎn)單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對(duì)象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支