這篇文章主要介紹了react-dnd如何實現(xiàn)拖拽的相關(guān)知識,內(nèi)容詳細易懂,操作簡單快捷,具有一定借鑒價值,相信大家閱讀完這篇react-dnd如何實現(xiàn)拖拽文章都會有所收獲,下面我們一起來看看吧。
成都創(chuàng)新互聯(lián)公司是一家專業(yè)提供蔡家坡企業(yè)網(wǎng)站建設(shè),專注與成都做網(wǎng)站、成都網(wǎng)站建設(shè)、html5、小程序制作等業(yè)務(wù)。10年已為蔡家坡眾多企業(yè)、政府機構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站建設(shè)公司優(yōu)惠進行中。
實現(xiàn)方法:1、利用“import{DndProvider}from 'react-dnd'”定義一個可拖拽的范圍;2、利用“import{useDrag}from 'react-dnd'”將DragSource包裹住組件,使其可以拖動即可。
本教程操作環(huán)境:Windows10系統(tǒng)、react17.0.1版、Dell G3電腦。
React DnD是React和Redux核心作者 Dan Abramov創(chuàng)造的一組React 高階組件,可以在保持組件分離的前提下幫助構(gòu)建復(fù)雜的拖放接口。
React DnD 的需求
默認使用 HTML5 拖放API,但支持
不直接操作 DOM
DOM 和拖放的源和目標(biāo)解耦
融入HTML5拖放中竊取類型匹配和數(shù)據(jù)傳遞的想法
React DnD 的特點
專注拖拽,不提供現(xiàn)成組件
React DnD提供了一組強大的原語,但它不包含任何現(xiàn)成組件,而是采用包裹使用者的組件并注入 props 的方式。 它比jQuery UI等更底層,專注于使拖放交互正確,而把視覺方面的效果例如坐標(biāo)限制交給使用者處理。這其實是一種關(guān)注點分離的原則,例如React DnD不打算提供可排序組件,但是使用者可以基于它快速開發(fā)任何需要的自定義的可排序組件。
單向數(shù)據(jù)流
類似于 React 一樣采取聲明式渲染,并且像 redux 一樣采用單向數(shù)據(jù)流架構(gòu),實際上內(nèi)部使用了 Redux
隱藏了平臺底層API的問題
HTML5拖放API充滿了陷阱和瀏覽器的不一致。 React DnD為您內(nèi)部處理它們,因此使用者可以專注于開發(fā)應(yīng)用程序而不是解決瀏覽器問題。
可擴展可測試
React DnD默認提供了HTML5拖放API封裝,但它也允許您提供自定義的“后端(backend)”。您可以根據(jù)觸摸事件,鼠標(biāo)事件或其他內(nèi)容創(chuàng)建自定義DnD后端。例如,內(nèi)置的模擬后端允許您測試Node環(huán)境中組件的拖放交互。
為未來做好了準(zhǔn)備
React DnD不會導(dǎo)出mixins,并且對任何組件同樣有效,無論它們是使用ES6類,createReactClass還是其他React框架創(chuàng)建的。而且API支持了ES7 裝飾器。
示例如下:
1.1.使用DndProvider定義一個可以拖拽的范圍
/* * @Author: muge * @Date: 2021-12-04 16:59:25 * @LastEditors: Please set LastEditors * @LastEditTime: 2021-12-08 14:24:47 */ import React, { useState } from 'react'; import { DndProvider } from 'react-dnd'; import { HTML5Backend } from 'react-dnd-html5-backend'; import SourceBox from './SourceBox'; import TargetBox from './TargetBox'; import TreeBox from './TreeBox'; const item: any[] = [ { id: 1, name: 'muge', }, { id: 2, name: 'muxi', }, { id: 3, name: 'mugege', }, ]; const Container = () => { // 當(dāng)前拖拽項 const [currentList, setCurrentList] = useState({}); return ( // 類似redux數(shù)據(jù)傳輸 需要在最外層包裹對象 ); }; export default Container; 拖拽源組件 列表-----樹
{/* 列表拖拽源 */} {item.map((itemz: any, index: number) => ({/* 注意,不要樹組件整體直接設(shè)置拖拽,抽成一個組件來遍歷每一項 =》自定義渲染*/} {/* 樹形拖拽源 */}))} 拖拽放置目標(biāo)
{/* 拖拽最終放置組件 */}
2.使用 DragSource 包裹住組件,使其可以進行拖動
/* * @Author: muge * @Date: 2021-12-07 14:26:08 * @LastEditors: Please set LastEditors * @LastEditTime: 2021-12-08 14:18:52 */ import { useDrag } from 'react-dnd'; const ItemTypes = { BOX: 'box', }; const style = { border: '1px dashed gray', backgroundColor: 'white', padding: '0.5rem 1rem', marginRight: '1rem', marginBottom: '1rem', cursor: 'move', }; const SourceBox = ({ item, setCurrentList }: any) => { const [{ opacity }, drag] = useDrag( () => ({ type: ItemTypes.BOX, collect: (monitor) => ({ opacity: monitor.isDragging() ? 0.4 : 1, }), item: () => item, //返回當(dāng)前列表項數(shù)據(jù) canDrag: (monitor) => { //是否取消拖拽 console.log(monitor, 'monitor131'); return true; }, // end(currentItem, monitor) { // monitor.getDropResult(); //獲取拖拽對象所處容器的數(shù)據(jù) // monitor.didDrop(); // 當(dāng)前容器能否放置拖拽對象 拖動停止時觸發(fā) monitor.didDrop() && setCurrentList(currentItem); //在容器點松開 才賦值 }, }), [], ); return ({item.id}------{item.name}); }; export default SourceBox;
3.使用 DropTarget 包裹住組件,使其對拖動,懸停或 dropped 的兼容項目做出反應(yīng)。
/* * @Author: muge * @Date: 2021-12-07 14:26:08 * @LastEditors: Please set LastEditors * @LastEditTime: 2021-12-08 14:33:08 */ import React from 'react'; import { useDrop } from 'react-dnd'; const ItemTypes = { BOX: 'box', }; const style: any = { border: '1px solid gray', height: '15rem', width: '15rem', padding: '2rem', textAlign: 'center', }; const TargetBox = ({ currentList }: any) => { const [{ isActive, isOver, canDrop }, drop] = useDrop(() => ({ accept: ItemTypes.BOX, collect: (monitor) => ({ isActive: monitor.canDrop() && monitor.isOver(), isOver: monitor.isOver(), canDrop: monitor.canDrop(), }), // hover: (item, monitor) => { // console.log(item, 'item'); // console.log(monitor, 'monitor'); // }, })); // console.log(isOver, 'isOver'); // console.log(canDrop, 'canDrop'); return ({isActive ? 'Release to drop' : 'Drag item here'}); }; export default TargetBox;{JSON.stringify(currentList) !== '{}' ? JSON.stringify(currentList) : '當(dāng)前item'}
關(guān)于“react-dnd如何實現(xiàn)拖拽”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“react-dnd如何實現(xiàn)拖拽”知識都有一定的了解,大家如果還想學(xué)習(xí)更多知識,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。