<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          這個(gè)17k star的拖拽庫有點(diǎn)料

          共 2863字,需瀏覽 6分鐘

           ·

          2022-02-19 03:04

          茶已備好,只待君來!感謝關(guān)注 前端點(diǎn)線面 (>?<),本號(hào)定期推薦原創(chuàng)深度好文,幫助每一位在前端領(lǐng)域打拼的伙伴們走向前列,此外關(guān)注我獲取最前沿知識(shí)點(diǎn)、海量學(xué)習(xí)資料、《前端百題斬》、大量思維導(dǎo)圖,并進(jìn)前端劃水交流群。


          一、背景

          近期在工作中遇到了一個(gè)新的需求,該需求需要實(shí)現(xiàn)某個(gè)組件的拖拽,面對(duì)這個(gè)需求的第一個(gè)項(xiàng)目肯定是問問度娘和用最大同性交友網(wǎng)站進(jìn)行搜索,最終皇天不負(fù)有心人,讓我找到了這個(gè)17k star的React拖拽庫——React DnD。

          image.png

          二、簡(jiǎn)單使用

          2.1 安裝

          npm?install?react-dnd?-S?//?react-dnd包,其核心包
          npm?install?react-dnd-html5-backend?-S?//?拖拽的底層實(shí)現(xiàn)所需要的庫

          2.2 三個(gè)核心點(diǎn)

          通過使用React DnD這個(gè)庫,我認(rèn)為里面最有用的部分包含一個(gè)組件和兩個(gè)Hook API,它們分別是:

          1. DndProvider組件
          2. useDrag函數(shù)
          3. useDrop函數(shù)

          2.2.1 DndProvider組件

          如果想讓某一內(nèi)容使用React DnD的能力,需要將該部分用DndProvider進(jìn)行包裹,其接收參數(shù)如下所示:

          • backend:必填。一個(gè)React DnD后端。目前官方文檔有三個(gè),分別為:react-dnd-html5-backend、react-dnd-touch-backend、react-dnd-test-backend,但是常用的還是react-dnd-html5-backend。
          • context:可選的。用于配置后端的后端上下文。這取決于后端實(shí)現(xiàn)。
          • options:可選的。用于配置后端的選項(xiàng)對(duì)象。這取決于后端實(shí)現(xiàn)。

          下面來一起看看該組件的簡(jiǎn)單使用:

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

          function?App()?{
          ??return?(
          ????<div?className="App">
          ??????<DndProvider?backend={HTML5Backend}>
          ????????此處將放拖拽相關(guān)內(nèi)容
          ??????DndProvider>

          ????div>
          ??);
          }

          export?default?App;

          2.2.2 useDrag函數(shù)

          既然知道了整個(gè)操縱空間,接下來需要了解的就是從什么位置進(jìn)行拖拽,該庫提供了useDrag hook API,該元素可以讓一個(gè)DOM元素實(shí)現(xiàn)拖拽效果。

          1. 參數(shù)

          (1) spec:創(chuàng)建規(guī)范對(duì)象的規(guī)范對(duì)象或函數(shù),其詳細(xì)內(nèi)容如下所示:

          1)type

          必須,是一個(gè)字符串或Symbol,只有drop和此值相同才可以進(jìn)行放置;

          2)item

          必須,用于描述被拖動(dòng)的數(shù)據(jù)

          3)previewOptions

          可選的,一個(gè)簡(jiǎn)單對(duì)象,用于描述拖動(dòng)預(yù)覽選項(xiàng);

          4)options

          可選的,一個(gè)簡(jiǎn)單對(duì)象

          5)end(item, monitor)

          可選的,當(dāng)拖拽停止,該函數(shù)被調(diào)用;

          6)canDrag(monitor)

          可選的,使用它指定當(dāng)前是否允許拖動(dòng);

          7)isDragging(monitor)

          可選的,默認(rèn)情況下,只有啟動(dòng)拖動(dòng)操作的拖動(dòng)源才被視為拖動(dòng);

          8)collect

          可選的,監(jiān)聽功能

          1. 返回值

          返回值是一個(gè)數(shù)組,數(shù)組內(nèi)容分別為:

          collected:一個(gè)對(duì)象,包含從collect函數(shù)收集的屬性,如果collect未定義函數(shù),則返回一個(gè)空對(duì)象;drag:拖動(dòng)器的連接器功能,必須附加到DOM的可拖動(dòng)部分;dragPreview:用于拖動(dòng)預(yù)覽的連接器功能,可以附加到DOM的預(yù)覽部分;

          1. 與拖動(dòng)部分建立連接

          通過ref屬性,將drag或dragPreview綁定到拖拽源上。

          下面一起來看看useDrag部分的使用

          import?{useDrag}?from?'react-dnd';

          const?SourceBox?=?props?=>?{
          ????const?{children}?=?props;

          ????/**
          ?????*?返回的參數(shù)
          ?????* collected:一個(gè)對(duì)象,包含從collect函數(shù)收集的屬性,如果collect未定義函數(shù),則返回一個(gè)空對(duì)象
          ?????* drag:拖動(dòng)器的連接器功能,必須附加到DOM的可拖動(dòng)部分
          ?????*?dragPreview:用于拖動(dòng)預(yù)覽的連接器功能,可以附加到DOM的預(yù)覽部分
          ?????*/

          ????const?[collected,?drag,?dragPreview]?=?useDrag({
          ????????//?只有drop和此值相同才可以進(jìn)行放置
          ????????type:?'box',
          ????????//?描述要拖動(dòng)的數(shù)據(jù)
          ????????item:?{
          ????????????detail:?'我是可以拖動(dòng)的數(shù)據(jù)!?。?
          ????????},
          ????????//?拖動(dòng)停止的手end將會(huì)被調(diào)用
          ????????end:?(item,?monitor)?=>?{
          ????????????//?getDropResult()獲取釋放后的結(jié)果
          ????????????console.log('monitor.getDropResult():',?monitor.getDropResult());
          ????????????//?source是否已經(jīng)drop在target
          ????????????console.log('monitor.didDrop()',?monitor.didDrop());
          ????????},
          ????????//?指定當(dāng)前是否允許拖動(dòng),默認(rèn)允許
          ????????canDrag:?monitor?=>?{
          ????????????return?true;
          ????????},
          ????????//?監(jiān)聽功能
          ????????collect:?(monitor,?props)?=>?{
          ????????????return?{
          ????????????????isDragging:?monitor.isDragging()
          ????????????};
          ????????}
          ????});
          ????return?(
          ????????<div?ref={drag}>
          ????????????{children}
          ????????div>

          ????);
          };

          export?default?SourceBox;

          2.2.3 useDrop函數(shù)

          為了將內(nèi)容放置到目標(biāo)位置,提供了useDrop函數(shù),如下所示:

          1. 參數(shù)

          (1) spec:創(chuàng)建規(guī)范對(duì)象的規(guī)范對(duì)象或函數(shù),其詳細(xì)內(nèi)容如下所示:

          1)accept

          必須,一個(gè)字符串,此放置目標(biāo)將僅對(duì)于指定類型的拖動(dòng)源產(chǎn)生的項(xiàng)目作出反應(yīng);

          2)options

          可選的,一個(gè)普通的對(duì)象;

          3)drop(item,monitor)

          可選的,當(dāng)兼容項(xiàng)目放在目標(biāo)時(shí)被調(diào)用;

          4)hover(item,monitor)

          可選的,將項(xiàng)目懸停在組件時(shí)調(diào)用;

          5)canDrop(item,monitor)

          可選的,用它來指定放置目標(biāo)是否接受該拖拽內(nèi)容;

          6)collect

          可選的,監(jiān)聽功能

          1. 返回值

          返回值是一個(gè)數(shù)組,數(shù)組內(nèi)容分別為:

          collected:一個(gè)對(duì)象,包含從collect函數(shù)收集的屬性,如果collect未定義函數(shù),則返回一個(gè)空對(duì)象;drop:一個(gè)用于放置目標(biāo)的連接器函數(shù),必須附加到DOM的放置部分;

          1. 與放置部分建立連接

          通過ref屬性,將drop與放置部分建立連接。

          下面一起來看看useDrop部分的使用

          import?{useDrop}?from?"react-dnd";

          const?TargetBox?=?()?=>?{
          ????const?[collected,?drop]?=?useDrop({
          ????????//??此放置目標(biāo)將僅對(duì)于指定類型的拖動(dòng)源產(chǎn)生的項(xiàng)目作出反應(yīng)
          ????????accept:?'box',
          ????????//?當(dāng)兼容項(xiàng)目放在目標(biāo)時(shí)調(diào)用
          ????????drop:?(item,?monitor)?=>?{
          ????????????console.log('我已經(jīng)被放到目標(biāo)?。?!')
          ????????},
          ????????//?監(jiān)聽功能
          ????????collect:?monitor?=>?{
          ????????????return?{
          ????????????????//?是否重疊
          ????????????????isOver:?monitor.isOver(),
          ????????????????//?是否可以放置
          ????????????????canDrop:?monitor.canDrop(),
          ????????????????item:?monitor.getItem(),
          ????????????????didDrop:?monitor.didDrop()
          ????????????};
          ????????}
          ????});

          ????return?(
          ????????<div?ref={drop}>
          ????????????<div?className="targetBox">
          ????????????????這是放置的區(qū)塊
          ????????????div>

          ????????div>
          ????);
          };

          export?default?TargetBox;

          2.3 monitor詳細(xì)內(nèi)容

          useDrag和useDrop上掛載了很多選項(xiàng),這些選項(xiàng)中很多存在monitor對(duì)象,該對(duì)象上掛載了很多方法,下面就簡(jiǎn)要概述幾個(gè)主要方法,如下所示:

          1. drag上的monitor上的方法

          2. drop上的monitor上的方法

          image.png

          三、效果圖

          1. 拖拽前
          image.png
          1. 拖拽中

          拖拽中拖拽的內(nèi)容跟隨鼠標(biāo)移動(dòng)

          image.png
          1. 拖拽后

          拖拽釋放鼠標(biāo)后,一些內(nèi)容被打印出來,打印的結(jié)果是先輸出drop中的內(nèi)容再輸出end中的內(nèi)容,所以我們想做一些處理最后在SourceBox中進(jìn)行處理,如果在drop中改變React相關(guān)的數(shù)據(jù)會(huì)報(bào)錯(cuò)。

          image.png

          四、學(xué)習(xí)感悟

          這個(gè)庫的資料千篇一律,在使用過程中遇到了一些坑,接下來與各位老鐵分享一下這些坑,防止后續(xù)深陷其中。

          1. end方法的調(diào)用時(shí)機(jī)晚于drop的調(diào)用時(shí)機(jī),所以只有在end中做釋放后的數(shù)據(jù)處理才能保證系統(tǒng)的正確性,如果在drop中就更新state或React redux中數(shù)據(jù),會(huì)引發(fā)錯(cuò)誤;
          2. item數(shù)據(jù)是從Drag到Drop之間的橋梁,在drag中定義的item數(shù)據(jù)可以通過monitor.getItem()獲取;
          3. drop回調(diào)的返回值是從Drop到Drag之間的橋梁,在end中可以通過monitor.getDropResult()其返回值;
          4. 一些掛載在monitor上的位置函數(shù)并不一定適用于所有的場(chǎng)景,需要引入DOM相關(guān)的位置操作。

          瀏覽 44
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          評(píng)論
          圖片
          表情
          推薦
          點(diǎn)贊
          評(píng)論
          收藏
          分享

          手機(jī)掃一掃分享

          分享
          舉報(bào)
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  操逼网页 | 成人精品视频网站 | 黄色在线视频网站 | 国产一级二级免费在线观看 | 日韩 欧美 亚洲 |