React 如何实现拖拽功能

阅读时长 7 分钟读完

在前端开发中,拖拽功能是非常常见的一种交互方式,React 作为一种流行的前端框架,自然也提供了一些方便的方式来实现拖拽功能。本文将介绍 React 实现拖拽功能的几种方式,包括原生拖拽API、第三方库react-dnd、自定义拖拽。

原生拖拽API

HTML5 引入了原生的拖拽API,React也可以很方便地使用这些API实现拖拽。在原生拖拽API中,需要借助 DragEvent 对象和相关属性进行操作。下面的代码展示了如何使用原生拖拽API实现拖拽功能:

-- -------------------- ---- -------
------ ------ ---------- ------- ---- --------

-------- ------------- -
  ----- --------- ----------- - ----------------
  ----- ----------- - -------------

  ----- --------------- - ------- -- -
    -----------------
    ----- ----------- - -------------
    ------------------- - ------------
    --------------------------------------- -------------
  -

  ----- ------------- - -- -- -
    ------------------
    ------------------- - -----
  -

  ----- -------------- - ------- -- -
    -----------------------
  -

  ------ -
    -----
      ----
        ----------------
        -----------------------------
        -------------------------
        ------------------- ------- - ------ - --------
      -
        -----
      ------
      ---- --------------------------------------
    ------
  --
-
展开代码

在上述代码中,我们通过 useState 和 useRef Hook 来记录拖拽状态和拖拽的目标元素。然后,我们分别实现了 handleDragStart 和 handleDragEnd 两个方法,用于处理拖拽开始和拖拽结束事件。在 handleDragStart 方法中,我们使用 dataTransfer 属性将拖拽的内容传递给 Drop 目标元素,并设置 dragged 状态以改变样式。在 handleDragEnd 方法中,我们还原 dragged 状态和清空 dragItemRef 引用。

react-dnd

除了原生API,还有一个流行的 React 拖拽库叫做 react-dnd。这个库提供了很多辅助函数和组件,可以轻松地实现高度可定制化的拖拽交互功能。下面的代码展示了如何使用 react-dnd 实现拖拽功能:

-- -------------------- ---- -------
------ ----- ---- --------
------ - -------- -------- ----------- - ---- ------------
------ - ------------ - ---- --------------------------

-------- ------------- -
  ----- -- ---------- -- ----- - ---------
    ----- - ----- ----- --
    -------- --------- -- --
      ----------- -----------------------
    ---
  ---

  ----- -- ------ -- ----- - ---------
    ------- ------
    ----- ------ -- ------------------
    -------- --------- -- --
      ------- -------------------
    ---
  ---

  ------ -
    -----
      ---- ---------- -------- -------- ---------- - --- - - ---
        -----
      ------
      ---- ---------- -------- ----------- ------ - ------ - ------ ---
        ----
      ------
    ------
  --
-

-------- ----- -
  ------ -
    ------------ -----------------------
      ------------ --
    --------------
  --
-
展开代码

在上述代码中,我们首先导入 useDraguseDrop 两个 Hook,然后在 DragAndDrop 组件中使用它们。我们使用 useDrag 定义拖拽项的 type 和相应的状态,使用 useDrop 定义接受拖拽的内容,并在接受到内容时调用 drop 函数处理。最后,我们使用 DndProvider 包裹 DragAndDrop 组件,并指定 HTML5Backend 作为后端。

react-dnd 还提供了更多高级的功能,如嵌套拖拽、拖拽时计算偏移量等。

自定义拖拽

如果原生API或 react-dnd 不能完全满足我们的需求,我们还可以自定义拖拽功能。自定义拖拽功能包括两个主要步骤:手动实现鼠标跟踪和位置计算,以及在目标元素上监听拖拽事件并实现相应的拖拽行为。

下面的代码展示了如何通过自定义拖拽实现一个抽屉式拖放效果:

-- -------------------- ---- -------
------ ------ - -------- - ---- --------

-------- ------------- -
  ----- ---------- ------------ - ---------- -- -- -- - ---
  ----- ---------- ------------ - ----------------

  ----- --------------- - ------- -- -
    ----- ------ - ----------- - -----------
    ----- ------ - ----------- - -----------

    ----- --------------- - ------- -- -
      ------------- -- ----------- - ------- -- ----------- - ------ ---
    --

    ----- ------------- - -- -- -
      -------------------
      --------------------------------------- -----------------
      ------------------------------------- ---------------
    --

    ------------------
    ------------------------------------ -----------------
    ---------------------------------- ---------------
  --

  ------ -
    ----
      ------------------- - ---------- - ---
      -------- ----- ----------- ---- ---------- --
      -----------------------------
    -
      -----
    ------
  --
-

-------- ----- -
  ------ ------------ ---
-
展开代码

在上述代码中,我们利用 useState 来记录位置信息和拖拽状态。然后,我们监听 onMouseDown 事件,通过计算鼠标在拖拽元素内的相对位置,得到需要拖移的距离,并在 handleMouseMove 事件中更新位置信息。最后,我们在 handleMouseUp 事件中清除 mousemovemouseup 事件监听器,以及设置拖拽状态。

结语

本文介绍了 React 实现拖拽功能的几种方式,分别是原生拖拽API、react-dnd 和自定义拖拽,它们各有优缺点,可以根据实际需求选择。希望本文能够帮助读者更好地理解 React 中的拖拽实现方式,并在实践中得到应用。

来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/678073b6ce7f4861253c24ac

纠错
反馈

纠错反馈