最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

react-dnd實(shí)現(xiàn)任意拖動與互換位置

 更新時(shí)間:2022年08月26日 15:36:22   作者:孤風(fēng)隨雨  
這篇文章主要為大家詳細(xì)介紹了react-dnd實(shí)現(xiàn)任意拖動與互換位置,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

本文實(shí)例為大家分享了react-dnd實(shí)現(xiàn)任意拖動與互換位置的具體代碼,供大家參考,具體內(nèi)容如下

react-dnd用法

hooks組件

1.使用DndProvider定義一個(gè)可以拖拽的范圍

import { HTML5Backend } from 'react-dnd-html5-backend';
import { DndProvider } from 'react-dnd';

class App extends Component{
? render () {
? ? return (
? ? ? <div>
? ? ? ? <DndProvider backend={HTML5Backend}>
? ? ? ? ? <Container />
? ? ? ? </DndProvider>
? ? ? </div>
? ? )
? }
}

2.定義drag和drop

drag:就是可以被拖拽的東西

drop: 就是拖拽后可以放的地方

import { useDrag } from 'react-dnd';

/**item:必填。描述了要拖動的數(shù)據(jù) ( 包含type: 對應(yīng)drop>accept )
begin(monitor): 可選的。拖動操作開始時(shí)觸發(fā)。
end(item, monitor): 可選的。當(dāng)拖動停止時(shí),end被調(diào)用。
canDrag(monitor): 可選的。使用它來指定當(dāng)前是否允許拖動。
isDragging(monitor): 可選的。默認(rèn)情況下,只有啟動拖動操作的拖動源才被視為拖動。
collect: 可選的。收集功能。它應(yīng)該返回道具的簡單對象以返回注入到組件中。它接收兩個(gè)參數(shù),monitor和props。
spec:必填。一個(gè)普通的JavaScript對象,上面有一些允許的方法。它描述了拖動源如何對拖放事件做出反應(yīng)。**/


const Drag = ({ name }) => {
? const [{isDragging}, drag] = useDrag({
? ? type: 'test',
? ? end(item, monitor) { ??
? ? ?? ?monitor.getDropResult() ? //獲取拖拽對象所處容器的數(shù)據(jù)
? ? ?? ?monitor.didDrop() ? ?// 當(dāng)前容器能否放置拖拽對象
? ? } ? ?
? })

? return (
? ? <div id="drag">{name}</div>
? )
}
import { useDrop } from 'react-dnd';

/**
參考api?
accept:必填。 (對應(yīng) drag item.type )
options: 可選的。一個(gè)普通的對象。
drop(item, monitor): 可選的。當(dāng)兼容項(xiàng)目放在目標(biāo)上時(shí)調(diào)用。
hover(item, monitor): 可選的。將項(xiàng)目懸停在組件上時(shí)調(diào)用。
canDrop(item, monitor): 可選的。使用它來指定放置目標(biāo)是否能夠接受該物品。如果要始終允許它,則只需忽略此方法。
collect: 可選的。收集功能。它應(yīng)該返回道具的簡單對象以返回注入到組件中。它接收兩個(gè)參數(shù),monitor和props
*/

const Container = (props) => {
? const [{isOver, canDrop}, drop] = useDrop({
? ? accept: 'test',
? ? drop: (item, monitor) => ({?
? ? ?? ?dropname: '測試',?
? ? ?? ?top: monitor.getDifferenceFromInitialOffset().y,
? ? ? ? left: monitor.getDifferenceFromInitialOffset().x?
? ? ?}), ?
? ? // 可以在這里配置數(shù)據(jù),與drag中monitor.getDropResult()獲取的信息關(guān)聯(lián)
? ? collect: (monitor) => ({
? ? ? isOver: monitor.isOver(), ? // 返回拖拽對象是否懸浮在該容器上
? ? ? canDrop: monitor.canDrop(), ?// 當(dāng)前容器是否支持拖拽對象放置
? ? })
? })

? return (
? ? <div ref={drop}>
?? ??? ?...
? ? </div>
? )
}

實(shí)現(xiàn)任意拖拽

1.在容器中通過drop —> monitor.getDifferenceFromInitialOffset()獲取拖拽對象當(dāng)前位置與初始位置的偏移量

2.在drag的end中,通過monitor.getDropResult()獲取到與初始位置的偏移量,給當(dāng)前拖拽元素的偏移量重新賦值,即可做到任意拖拽

3.如果同時(shí)有很多個(gè)可拖拽的對象,需要給他們定義一個(gè)index值, 因?yàn)檫@個(gè)可拖拽組件是復(fù)用的,所以我們獲取到的拖拽對象是個(gè)數(shù)組,我們可以用index作為下標(biāo),給當(dāng)前拖拽組件單獨(dú)賦值

const Drag = ({ name, top, left, index }) => {
? const [{isDragging}, drag] = useDrag({
? ? type: 'test',
? ? end(item, monitor) {
? ? ? console.log(item);
? ? ? if(monitor.didDrop()){
? ? ? ? const droptarget = monitor.getDropResult();
? ? ? ? const top = document.querySelectorAll('#drag')[index].offsetTop;
? ? ? ? const left = document.querySelectorAll('#drag')[index].offsetLeft;
? ? ? ? document.querySelectorAll('#drag')[index].style.top = (top + droptarget.top) + 'px';
? ? ? ? document.querySelectorAll('#drag')[index].style.left = (left + droptarget.left) + 'px';
? ? ? }else{
? ? ? ? console.log(monitor.getDropResult());
? ? ? }
? ? }
? })

? return (
? ? <div id="drag" index={index} ref={drag} style={{position: 'absolute', top: `${top}`, left: `${left}`, width: '70px', height: '40px', border: '1px solid black'}}>{name}</div>
? )
}
const Container = (props) => {
? const [{isOver, canDrop}, drop] = useDrop({
? ? accept: 'test',
? ? drop: (item, monitor) => ({ dropname: '測試', top: monitor.getDifferenceFromInitialOffset().y, left: monitor.getDifferenceFromInitialOffset().x }),
? ? collect: (monitor) => ({
? ? ? isOver: monitor.isOver(),
? ? ? canDrop: monitor.canDrop(),
? ? })
? })

? return (
? ? <div
? ? ? id="drop1"
? ? ? ref={drop}
? ? ? style={{width: '700px', height: '600px', backgroundColor: 'yellow'}}
? ? >

? ? </div>
? )
}

拖拽互換位置

拖拽互換位置需要組件既是drag拖拽對象,也是drop拖拽容器。所以使用useRef()定義ref,然后 drag(drop(ref)),讓它即作為拖拽對象也作為拖拽容器,然后定義拖拽結(jié)束事件

import React, { useRef, useMemo } from 'react';
import { useDrag, useDrop } from 'react-dnd';
import { item } from './itemType';

const style = {
? display: 'inline',
? border: '1px dashed gray',
? padding: '0.5rem 1rem',
? marginRight: '30px',
? marginTop: '.5rem',
? backgroundColor: 'blue',
? cursor: 'move',
? borderRadius: '50%',
? position: 'relative',
};

const Drag = (props) => {
? const ref = useRef()

? const [{}, drop] = useDrop({
? ? accept: item.type,
? ? drop: (item, monitor) => {
? ? ? ? return {
? ? ? ? ? index: props.index
? ? ? ? }
? ? }
? })

? const count = useMemo(() => {
? ? document.getElementById('delete').oncontextmenu = (e) => {
? ? ? e.preventDefault();
? ? }
? },[1])

? const [{}, drag] = useDrag({
? ? type: item.type,
? ? end: (item, monitor) => {
? ? ? console.log(monitor.didDrop());
? ? ? if(monitor.didDrop()){
? ? ? ? const dropResult = monitor.getDropResult();
? ? ? ? props.changePosition([props.index, dropResult.index])
? ? ? }else{
? ? ? ? return;
? ? ? }
? ? }
? })

? drag(drop(ref))

? return (
? ? <div id="delete" ref={ref} id="drag" index={props.index} style={{...style}} >
? ? ? <span>{props.name}</span>
? ? ? <span style={{position: 'absolute', border: '1px solid gray', top: "18.5px", left: '145px', width: '29px',background: 'gray'}}></span>
? ? </div>
? )
}

以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

  • react使用axios進(jìn)行api網(wǎng)絡(luò)請求的封裝方法詳解

    react使用axios進(jìn)行api網(wǎng)絡(luò)請求的封裝方法詳解

    這篇文章主要為大家詳細(xì)介紹了react使用axios進(jìn)行api網(wǎng)絡(luò)請求的封裝方法,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下,希望能夠給你帶來幫助
    2022-03-03
  • 詳解React中組件之間通信的方式

    詳解React中組件之間通信的方式

    這篇文章主要介紹了React中組件之間通信的方式,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-07-07
  • 深入理解React中何時(shí)使用箭頭函數(shù)

    深入理解React中何時(shí)使用箭頭函數(shù)

    對于剛學(xué)前端的大家來說,對于React中的事件監(jiān)聽寫法有所疑問很正常,特別是React中箭頭函數(shù)使用這塊,下面這篇文章主要給大家深入的講解了關(guān)于React中何時(shí)使用箭頭函數(shù)的相關(guān)資料,需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧。
    2017-08-08
  • 詳解react-webpack2-熱模塊替換[HMR]

    詳解react-webpack2-熱模塊替換[HMR]

    這篇文章主要介紹了詳解react-webpack2-熱模塊替換[HMR], 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧
    2017-08-08
  • React找不到模塊“./index.module.scss”或其相應(yīng)的類型聲明及解決方法

    React找不到模塊“./index.module.scss”或其相應(yīng)的類型聲明及解決方法

    這篇文章主要介紹了React找不到模塊“./index.module.scss”或其相應(yīng)的類型聲明及解決方法,本文給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-09-09
  • 工程級?React?注冊登錄全棧級流程分析

    工程級?React?注冊登錄全棧級流程分析

    這篇文章主要介紹了工程級?React?注冊登錄全棧級流程,本文結(jié)合實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2023-02-02
  • react-router?重新加回跳轉(zhuǎn)攔截功能詳解

    react-router?重新加回跳轉(zhuǎn)攔截功能詳解

    這篇文章主要為大家介紹了react-router?重新加回跳轉(zhuǎn)攔截功能詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • 詳解React中常見的三種路由處理方式選擇

    詳解React中常見的三種路由處理方式選擇

    這篇文章主要為大家詳細(xì)介紹了React中常見的三種路由處理方式該如何選擇,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下
    2024-01-01
  • React?在非組件環(huán)境切換路由的方法

    React?在非組件環(huán)境切換路由的方法

    這篇文章主要介紹了React?在非組件環(huán)境切換路由的方法,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友參考下吧
    2023-10-10
  • React實(shí)現(xiàn)表格選取

    React實(shí)現(xiàn)表格選取

    這篇文章主要為大家詳細(xì)介紹了React實(shí)現(xiàn)表格選取,類似于Excel選中一片區(qū)域并獲得選中區(qū)域的所有數(shù)據(jù),文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2022-08-08

最新評論

邯郸市| 微山县| 汶川县| 安康市| 咸宁市| 苏尼特右旗| 邹平县| 永修县| 澎湖县| 鄂托克前旗| 上饶县| 紫金县| 交口县| 南阳市| 河东区| 绥芬河市| 武山县| 苍南县| 炉霍县| 汉沽区| 成武县| 化州市| 化州市| 崇信县| 上虞市| 东海县| 偃师市| 乾安县| 淄博市| 锡林浩特市| 安庆市| 腾冲县| 海南省| 昔阳县| 酒泉市| 泰安市| 读书| 梓潼县| 保定市| 盐亭县| 吴堡县|