靖奇 發表於 2021-6-4 22:28:00

react-dnd 用法详解

<p>本文详细讲解了 react-dnd 的 API 以及用法,并且附上了可供参考的 Demo,希望能够给需要的朋友提供一下帮助。</p>
<hr>
<h2>一、概念</h2>
<p>React DnD 是一组 React 高阶组件,使用的时候只需要使用对应的 API 将目标组件进行包裹,即可实现拖动或接受拖动元素的功能。将拖动的事件转换成对象中对应状态的形式,不需要开发者自己判断拖动状态,只需要在传入的 spec 对象中各个状态属性中做对应处理即可。刚刚接触可能难以理解,真正熟悉用法之后会感觉很方便。</p>
<blockquote>
<p>本文&nbsp;<code>Demo</code>&nbsp;地址:react-dnd-dustbin。如有帮助,欢迎 Star。</p>
</blockquote>
<hr>
<h2>二、DragSource:使组件能够被拖拽</h2>
<blockquote>
<p>使用&nbsp;<code>DragSource</code>&nbsp;包裹住组件,使其可以进行拖动。</p>
</blockquote>
<h3>使用方式</h3>
<ol class="hljs-ln">
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">import <span class="hljs-type">React, { <span class="hljs-type">Component } from <span class="hljs-symbol">'react';</span></span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">import { <span class="hljs-type">DragSource } from <span class="hljs-symbol">'react-dnd';</span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">const spec = {</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">beginDrag(props, monitor, component) {</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// 这里 return 出去的对象属性自行选择,这里只是用 id 作为演示</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">return { id: props.id }</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">endDrag(props, monitor, component) {</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">...</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">canDrag(props, monitor) {</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">...</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">isDragging(props, monitor) {</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">...</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">const collect = (connect, monitor) =&gt; ({</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// 这里返回一个对象,会将对象的属性都赋到组件的 props 中去。这些属性需要自己定义。</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">connectDropTarget: connect.dropTarget(),</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">id: monitor.getItem().id</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">})</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-meta">@DragSource(<span class="hljs-class"><span class="hljs-keyword">type, <span class="hljs-title">spec, <span class="hljs-title">collect)</span></span></span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">MyComponent <span class="hljs-keyword">extends <span class="hljs-title">Component {</span></span></span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">/* ... */</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">export <span class="hljs-keyword">default <span class="hljs-type">MyComponent;</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">复制代码</div>
</div>
</li>
</ol>
<p>参数讲解:</p>
<ul>
<li>type: 必填。字符串,ES6符号或返回给定组件的函数props。只有为相同类型注册的&nbsp;<code>drop targets</code>&nbsp;才会对此拖动源生成的项目做出反应</li>
<li>spec:必填。一个普通的JavaScript对象,上面有一些允许的方法。它描述了拖动源如何对拖放事件做出反应。</li>
<li>collect:必填。收集功能。它应该返回一个普通的对象注入你的组件。它接收两个参数:connect和monitor。</li>
<li>options:可选的。一个普通的对象。</li>
</ul>
<h3>spec 对象中的方法</h3>
<ul>
<li>
<p><code>beginDrag(props, monitor, component)</code>:必填。当拖动开始时,<code>beginDrag</code>&nbsp;被调用。您必须返回描述被拖动数据的纯&nbsp;<code>JavaScript</code>&nbsp;对象。您返回的内容会被放置到&nbsp;<code>monitor.getItem()</code>&nbsp;获取到的对象中。</p>
</li>
<li>
<p><code>endDrag(props, monitor, component)</code>:可选的。当拖动停止时,<code>endDrag</code>&nbsp;被调用。对于每个&nbsp;<code>beginDrag</code>,<code>endDrag</code>&nbsp;都会对应。</p>
</li>
<li>
<p><code>canDrag(props, monitor)</code>: 可选的。用它来指定当前是否允许拖动。如果您想要始终允许它,只需省略此方法即可。注意:您可能无法调用<code>monitor.canDrag()</code>&nbsp;此方法。</p>
</li>
<li>
<p><code>isDragging(props, monitor)</code>: 可选的。默认情况下,仅启动拖动操作的拖动源被视为拖动。注意:您可能无法调用&nbsp;<code>monitor.isDragging()</code>&nbsp;此方法。</p>
</li>
</ul>
<h3>方法中的参数 props, monitor, component</h3>
<ul>
<li><code>props</code>:当前组件的&nbsp;<code>props</code></li>
<li><code>monitor</code>:一个&nbsp;<code>DragSourceMonitor</code>&nbsp;实例。使用它来查询有关当前拖动状态的信息,例如当前拖动的项目及其类型,当前和初始坐标和偏移,以及它是否已被删除。</li>
<li><code>component</code>:指定时,它是组件的实例。使用它来访问底层DOM节点以进行位置或大小测量,或调用&nbsp;<code>setState</code>&nbsp;以及其他组件方法。<code>isDragging</code>、&nbsp;<code>canDrag</code>&nbsp;方法里获取不到&nbsp;<code>component</code>&nbsp;这个参数,因为它们被调用时实例可能不可用</li>
</ul>
<h3>collect 中的 connect 和 monitor 参数</h3>
<ul>
<li>
<p><code>connect</code>: 一个&nbsp;<code>DragSourceConnector</code>&nbsp;实例。它有两种方法:dragPreview()和dragSource()。</p>
<ul>
<li>dragSource() =&gt; (elementOrNode, options?):常用方法,返回一个函数,传递给组件用来将 source DOM 和 React DnD Backend 连接起来
<ul>
<li>dragPreview():返回一个函数,传递给组件用来将拖动时预览的 DOM 节点 和 React DnD Backend 连接起来</li>
</ul>
</li>
</ul>
</li>
<li>
<p>monitor:一个&nbsp;<code>DragSourceMonitor</code>&nbsp;实例。包含下面各种方法:</p>
</li>
</ul>
<div class="table-box">
<table>
<thead>
<tr><th>方法</th><th>含义</th></tr>
</thead>
<tbody>
<tr>
<td><code>canDrag()</code></td>
<td>是否可以被拖拽。如果没有正在进行拖动操作,则返回 true</td>
</tr>
<tr>
<td><code>isDragging()</code></td>
<td>是否正在被拖动。如果正在进行拖动操作,则返回 true</td>
</tr>
<tr>
<td><code>getItemType()</code></td>
<td>返回标识当前拖动项的类型的字符串或ES6符号。 如果没有拖动项目,则返回&nbsp;<code>null</code></td>
</tr>
<tr>
<td><code>getItem()</code></td>
<td>返回表示当前拖动项的普通对象。 每个拖动源都必须通过从其beginDrag()方法返回一个对象来指定它。 如果没有拖动项目,则返回&nbsp;<code>null</code></td>
</tr>
<tr>
<td><code>getDropResult()</code></td>
<td>返回表示最后记录的放置&nbsp;<code>drop result</code>&nbsp;对象</td>
</tr>
<tr>
<td><code>didDrop()</code></td>
<td>如果某个&nbsp;<code>drop target</code>&nbsp;处理了&nbsp;<code>drop</code>&nbsp;事件,则返回 true,否则返回 false。即使&nbsp;<code>target</code>&nbsp;没有返回&nbsp;<code>drop</code>&nbsp;结果,<code>didDrop()</code>&nbsp;也会返回true。 在&nbsp;<code>endDrag()</code>&nbsp;中使用它来测试任何放置目标是否已处理掉落。 如果在&nbsp;<code>endDrag()</code>&nbsp;之外调用,则返回 false</td>
</tr>
<tr>
<td><code>getInitialClientOffset()</code></td>
<td>返回当前拖动操作开始时指针的{x,y}&nbsp;<code>client</code>&nbsp;偏移量。 如果没有拖动项目,则返回&nbsp;<code>null</code></td>
</tr>
<tr>
<td><code>getInitialSourceClientOffset()</code></td>
<td>返回当前拖动操作开始时&nbsp;<code>drag source</code>&nbsp;组件的根DOM节点的{x,y}<code>client</code>&nbsp;偏移量。 如果没有拖动项目,则返回&nbsp;<code>null</code></td>
</tr>
<tr>
<td><code>getClientOffset()</code></td>
<td>拖动操作正在进行时,返回指针的最后记录的{x,y}<code>client</code>&nbsp;偏移量。 如果没有拖动项目,则返回&nbsp;<code>null</code></td>
</tr>
<tr>
<td><code>getDifferenceFromInitialOffset()</code></td>
<td>返回当前拖动操作开始时鼠标的最后记录&nbsp;<code>client</code>&nbsp;偏移量与&nbsp;<code>client</code>&nbsp;偏移量之间的{x,y}差异。 如果没有拖动项目,则返回&nbsp;<code>null</code></td>
</tr>
<tr>
<td><code>getSourceClientOffset()</code></td>
<td>返回&nbsp;<code>drag source</code>&nbsp;组件的根DOM节点的预计{x,y}&nbsp;<code>client</code>&nbsp;偏移量,基于其在当前拖动操作开始时的位置以及移动差异。 如果没有拖动项目,则返回&nbsp;<code>null</code></td>
</tr>
</tbody>
</table>
</div>
<hr>
<h2>三、DropTarget:使组件能够放置拖拽组件</h2>
<blockquote>
<p>使用&nbsp;<code>DropTarget</code>&nbsp;包裹住组件,使其对拖动,悬停或 dropped 的兼容项目做出反应。</p>
</blockquote>
<h3>使用方式</h3>
<ol class="hljs-ln">
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">import <span class="hljs-type">React, { <span class="hljs-type">Component } from <span class="hljs-symbol">'react';</span></span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">import { <span class="hljs-type">DropTarget } from <span class="hljs-symbol">'react-dnd';</span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">const spec = {</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">drop(props, monitor, component) {</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// 这里 return 出去的对象属性自行选择,这里只是用 id 作为演示</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">return { id: props.id }</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">hover(props, monitor, component) {</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">...</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">canDrop(props, monitor) {</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">...</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">const collect = (connect, monitor) =&gt; ({</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// 这里返回一个对象,会将对象的属性都赋到组件的 props 中去。这些属性需要自己定义。</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">connectDropTarget: connect.dropTarget()</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">})</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-meta">@DropTarget(<span class="hljs-class"><span class="hljs-keyword">type, <span class="hljs-title">spec, <span class="hljs-title">collect)</span></span></span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">MyComponent <span class="hljs-keyword">extends <span class="hljs-title">Component {</span></span></span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">/* ... */</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">export <span class="hljs-keyword">default <span class="hljs-type">MyComponent;</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">复制代码</div>
</div>
</li>
</ol>
<p>参数讲解:</p>
<ul>
<li>type: 必填。字符串,ES6符号或返回给定组件的函数props。此放置目标仅对指定类型的&nbsp;<code>drag sources</code>&nbsp;项目做出反应</li>
<li>spec:必填。一个普通的JavaScript对象,上面有一些允许的方法。它描述了放置目标如何对拖放事件做出反应。</li>
<li>collect:必填。收集功能。它应该返回一个普通的道具对象注入你的组件。它接收两个参数:connect 和 monitor。</li>
<li>options:可选的。一个普通的对象。</li>
</ul>
<h3>spec 对象中的方法</h3>
<ul>
<li>
<p><code>drop(props, monitor, component)</code>: 可选的。在目标上放置兼容项目时调用。可以返回&nbsp;<code>undefined</code>&nbsp;或普通对象。如果返回一个对象,它将成为放置结果,可以使用&nbsp;<code>monitor.getDropResult()</code>&nbsp;获取到。</p>
</li>
<li>
<p><code>hover(props, monitor, component)</code>: 可选的。当项目悬停在组件上时调用。您可以检查&nbsp;<code>monitor.isOver({ shallow: true })</code>&nbsp;以测试悬停是仅发生在当前目标上还是嵌套上。</p>
</li>
<li>
<p><code>canDrop(props, monitor)</code>: 可选的。使用它来指定放置目标是否能够接受该项目。如果想要始终允许它,只需省略此方法即可。</p>
</li>
</ul>
<blockquote>
<p>文档没有提供按目的处理进入或离开事件的方法。而是&nbsp;<code>monitor.isOver()</code>&nbsp;从收集函数返回调用结果,以便我们可以使用&nbsp;<code>componentDidUpdateReact</code>&nbsp;钩子函数来处理组件中的进入和离开事件。</p>
</blockquote>
<h3>方法中的参数 props, monitor, component</h3>
<ul>
<li><code>props</code>:当前组件的&nbsp;<code>props</code></li>
<li><code>monitor</code>:一个&nbsp;<code>DropTargetMonitor</code>&nbsp;实例。使用它来查询有关当前拖动状态的信息,例如当前拖动的项目及其类型,当前和初始坐标和偏移,是否超过当前目标,以及是否可以删除它。</li>
<li><code>component</code>:指定时,它是组件的实例。使用它来访问底层DOM节点以进行位置或大小测量,或调用&nbsp;<code>setState</code>&nbsp;以及其他组件方法。<code>canDrag</code>&nbsp;方法里获取不到&nbsp;<code>component</code>&nbsp;这个参数,因为它们被调用时实例可能不可用。</li>
</ul>
<h3>collect 中的 connect 和 monitor 参数</h3>
<ul>
<li>
<p><code>connect</code>: 一个&nbsp;<code>DropTargetConnector</code>&nbsp;实例。它只有一种&nbsp;<code>dropTarget()</code>&nbsp;方法。</p>
<ul>
<li><code>dropTarget() =&gt; (elementOrNode)</code>:常用方法,返回一个函数,传递给组件用来将 target DOM 和 React DnD Backend 连接起来。通过{ connectDropTarget: connect.dropTarget() }从收集函数返回,可以将任何React元素标记为可放置节点。</li>
</ul>
</li>
<li>
<p>monitor:一个&nbsp;<code>DropTargetMonitor</code>&nbsp;实例。包含下面各种方法:</p>
</li>
</ul>
<div class="table-box">
<table>
<thead>
<tr><th>方法</th><th>含义</th></tr>
</thead>
<tbody>
<tr>
<td><code>canDrop()</code></td>
<td>是否可以被放置。如果正在进行拖动操作,则返回true</td>
</tr>
<tr>
<td><code>isOver(options)</code></td>
<td><code>drag source</code>&nbsp;是否悬停在&nbsp;<code>drop target</code>&nbsp;区域。可以选择传递<code>{ shallow: true }</code>以严格检查是否只有&nbsp;<code>drag source</code>&nbsp;悬停,而不是嵌套目标</td>
</tr>
<tr>
<td><code>getItemType()</code></td>
<td>返回标识当前拖动项的类型的字符串或ES6符号。如果没有拖动项目则返回&nbsp;<code>null</code></td>
</tr>
<tr>
<td><code>getItem()</code></td>
<td>返回表示当前拖动项的普通对象,每个拖动源都必须通过从其beginDrag()方法返回一个对象来指定它。如果没有拖动项目则返回&nbsp;<code>null</code></td>
</tr>
<tr>
<td><code>getDropResult()</code></td>
<td>返回表示最后记录的放置&nbsp;<code>drop result</code>&nbsp;对象</td>
</tr>
<tr>
<td><code>didDrop()</code></td>
<td>如果某个&nbsp;<code>drop target</code>&nbsp;处理了&nbsp;<code>drop</code>&nbsp;事件,则返回 true,否则返回 false。即使&nbsp;<code>target</code>&nbsp;没有返回&nbsp;<code>drop</code>&nbsp;结果,<code>didDrop()</code>&nbsp;也会返回true。 在&nbsp;<code>endDrag()</code>&nbsp;中使用它来测试任何放置目标是否已处理掉落。 如果在&nbsp;<code>endDrag()</code>&nbsp;之外调用,则返回 false</td>
</tr>
<tr>
<td><code>getInitialClientOffset()</code></td>
<td>返回当前拖动操作开始时指针的{x,y}&nbsp;<code>client</code>&nbsp;偏移量。 如果没有拖动项目,则返回&nbsp;<code>null</code></td>
</tr>
<tr>
<td><code>getInitialSourceClientOffset()</code></td>
<td>返回当前拖动操作开始时&nbsp;<code>drag source</code>&nbsp;组件的根DOM节点的{x,y}<code>client</code>&nbsp;偏移量。 如果没有拖动项目,则返回&nbsp;<code>null</code></td>
</tr>
<tr>
<td><code>getClientOffset()</code></td>
<td>拖动操作正在进行时,返回指针的最后记录的{x,y}<code>client</code>&nbsp;偏移量。 如果没有拖动项目,则返回&nbsp;<code>null</code></td>
</tr>
<tr>
<td><code>getDifferenceFromInitialOffset()</code></td>
<td>返回当前拖动操作开始时鼠标的最后记录&nbsp;<code>client</code>&nbsp;偏移量与&nbsp;<code>client</code>&nbsp;偏移量之间的{x,y}差异。 如果没有拖动项目,则返回&nbsp;<code>null</code></td>
</tr>
<tr>
<td><code>getSourceClientOffset()</code></td>
<td>返回&nbsp;<code>drag source</code>&nbsp;组件的根DOM节点的预计{x,y}&nbsp;<code>client</code>&nbsp;偏移量,基于其在当前拖动操作开始时的位置以及移动差异。 如果没有拖动项目,则返回&nbsp;<code>null</code></td>
</tr>
</tbody>
</table>
</div>
<hr>
<h2>四、DragDropContext &amp; DragDropContextProvider</h2>
<blockquote>
<p>注意:&nbsp;使用 DragSource 和 DropTarget 包裹的组件,必须放在: DragDropContext 包裹的根组件内部,或者 DragDropContextProvider 根标签的内部。</p>
</blockquote>
<h3>DragDropContext</h3>
<p>使用&nbsp;<code>DragDropContext</code>&nbsp;包装应用程序的根组件以启用 React DnD。</p>
<p>用法</p>
<ol class="hljs-ln">
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">import <span class="hljs-type">React, { <span class="hljs-type">Component } from <span class="hljs-symbol">'react';</span></span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">import <span class="hljs-type">HTML5Backend from <span class="hljs-symbol">'react-dnd-html5-backend';</span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">import { <span class="hljs-type">DragDropContext } from <span class="hljs-symbol">'react-dnd';</span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-meta">@DragDropContext(<span class="hljs-type">HTML5Backend)</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">YourApp <span class="hljs-keyword">extends <span class="hljs-title">Component {</span></span></span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">/* ... */</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">export <span class="hljs-keyword">default <span class="hljs-type">YourApp;</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">复制代码</div>
</div>
</li>
</ol>
<p>参数</p>
<ul>
<li>
<p>backend:必填。一个 React DnD 后端。除非您正在编写自定义的,否则建议使用 React DnD 附带的 HTML5Backend。</p>
</li>
<li>
<p>context:backend 依赖。用于自定义后端的上下文对象。例如,HTML5Backend可以为iframe场景注入自定义窗口对象。</p>
</li>
</ul>
<h3>DragDropContextProvider</h3>
<p>作为&nbsp;<code>DragDropContext</code>&nbsp;的替代方法,您可以使用&nbsp;<code>DragDropContextProvider</code>&nbsp;元素为应用程序启用React DnD。与&nbsp;<code>DragDropContext</code>&nbsp;类似,这可以通过&nbsp;<code>backendprop</code>&nbsp;注入后端,但也可以注入一个&nbsp;<code>window</code>&nbsp;对象。</p>
<p>用法</p>
<ol class="hljs-ln">
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">import <span class="hljs-type">React, { <span class="hljs-type">Component } from <span class="hljs-symbol">'react';</span></span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">import <span class="hljs-type">HTML5Backend from <span class="hljs-symbol">'react-dnd-html5-backend';</span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">import { <span class="hljs-type">DragDropContextProvider } from <span class="hljs-symbol">'react-dnd';</span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">export <span class="hljs-keyword">default <span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">YourApp <span class="hljs-keyword">extends <span class="hljs-title">Component {</span></span></span></span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">render() {</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">return (</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">&lt;<span class="hljs-type">DragDropContextProvider backend={<span class="hljs-type">HTML5Backend}&gt;</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">/* ... */</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">&lt;/<span class="hljs-type">DragDropContextProvider&gt;</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">)</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">复制代码</div>
</div>
</li>
</ol>
<p>参数</p>
<ul>
<li>
<p>backend:必填。一个 React DnD 后端。除非您正在编写自定义的,否则建议使用 React DnD 附带的 HTML5Backend。</p>
</li>
<li>
<p>context:backend 依赖。用于自定义后端的上下文对象。例如,HTML5Backend可以为iframe场景注入自定义窗口对象。</p>
</li>
</ul>
<hr>
<h2>五、react-dnd 的简单示例</h2>
<p>本示例参照官方的 Dustbin 示例进行讲解。</p>
<h3>项目准备</h3>
<p>当前项目使用&nbsp;<code>create-react-app</code>&nbsp;脚手架进行搭建,而且使用&nbsp;<code>react-dnd</code>&nbsp;时都是使用装饰器语法进行编写。所以需要先在项目里添加一些配置。</p>
<p>启用装饰器的配置方式可以参考我的上一篇文章:在 create-react-app 中启用装饰器语法。</p>
<p>新建&nbsp;<code>components</code>&nbsp;文件夹,用来存放编写的组件。新建&nbsp;<code>types</code>&nbsp;文件夹,用来存放&nbsp;<code>type</code>&nbsp;字符串常量,在&nbsp;<code>types</code>&nbsp;目录下创建&nbsp;<code>index.js</code>&nbsp;文件声明对应的&nbsp;<code>type</code>&nbsp;值。</p>
<p><code>types/index.js</code></p>
<ol class="hljs-ln">
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-selector-tag">export <span class="hljs-selector-tag">default {</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attribute">BOX: <span class="hljs-string">'box'</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">复制代码</div>
</div>
</li>
</ol>
<p>所以当前项目&nbsp;<code>src</code>&nbsp;目录下文件结构如下:</p>
<ol class="hljs-ln">
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">src</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">├── components/</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">├── types/</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">└── <span class="hljs-keyword">index.js</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">├── App.js</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">├── <span class="hljs-keyword">index.css</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">└── <span class="hljs-keyword">index.js</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">复制代码</div>
</div>
</li>
</ol>
<h3>创建 Box 组件,作为 DragSource</h3>
<p>在&nbsp;<code>components</code>&nbsp;目录下,创建&nbsp;<code>Box.js</code>&nbsp;文件,编写&nbsp;<code>Box</code>&nbsp;组件,使其可以进行拖动</p>
<p><code>components/Box.js</code></p>
<ol class="hljs-ln">
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">import React <span class="hljs-keyword">from <span class="hljs-string">'react';</span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">import PropTypes <span class="hljs-keyword">from <span class="hljs-string">'prop-types';</span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">import { DragSource } <span class="hljs-keyword">from <span class="hljs-string">'react-dnd';</span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">import ItemTypes <span class="hljs-keyword">from <span class="hljs-string">'../types';</span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">const style = {</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">border: <span class="hljs-string">'1px dashed gray',</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">backgroundColor: <span class="hljs-string">'white',</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">padding: <span class="hljs-string">'0.5rem 1rem',</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">marginRight: <span class="hljs-string">'1.5rem',</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">marginBottom: <span class="hljs-string">'1.5rem',</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">cursor: <span class="hljs-string">'move',</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">float: <span class="hljs-string">'left',</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">const boxSource = {</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">/**</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment"> * 开始拖拽时触发当前函数</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment"> * @param {*} props 组件的 props</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment"> */</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">beginDrag(props) {</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// 返回的对象可以在 monitor.getItem() 中获取到</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">return {</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">name: props.name,</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">},</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">/**</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment"> * 拖拽结束时触发当前函数</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment"> * @param {*} props 当前组件的 props</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment"> * @param {*} monitor DragSourceMonitor 对象</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment"> */</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">endDrag(props, monitor) {</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// 当前拖拽的 item 组件</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">const item = monitor.getItem()</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// 拖拽元素放下时,drop 结果</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">const dropResult = monitor.getDropResult()</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// 如果 drop 结果存在,就弹出 alert 提示</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">if (dropResult) {</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">alert(<span class="hljs-string">`You dropped <span class="hljs-subst">${item.name} into <span class="hljs-subst">${dropResult.name}!`)</span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">},</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">@DragSource(</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// type 标识,这里是字符串 'box'</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">ItemTypes.BOX,</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// 拖拽事件对象</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">boxSource,</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// 收集功能函数,包含 connect 和 monitor 参数</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// connect 里面的函数用来将 DOM 节点与 react-dnd 的 backend 建立联系</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-function">(<span class="hljs-params">connect, monitor) =&gt; ({</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// 包裹住 DOM 节点,使其可以进行拖拽操作</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">connectDragSource: connect.dragSource(),</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// 是否处于拖拽状态</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">isDragging: monitor.isDragging(),</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}),</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">)</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">Box <span class="hljs-keyword">extends <span class="hljs-title">React.<span class="hljs-title">Component {</span></span></span></span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">static propTypes = {</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">name: PropTypes.string.isRequired,</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">isDragging: PropTypes.bool.isRequired,</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">connectDragSource: PropTypes.func.isRequired</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">render() {</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">const { isDragging, connectDragSource } = <span class="hljs-built_in">this.props</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">const { name } = <span class="hljs-built_in">this.props</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">const opacity = isDragging ? <span class="hljs-number">0.4 : <span class="hljs-number">1</span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// 使用 connectDragSource 包裹住 DOM 节点,使其可以接受各种拖动 API</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// connectDragSource 包裹住的 DOM 节点才可以被拖动</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">return connectDragSource &amp;&amp; connectDragSource(</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="xml">&lt;<span class="hljs-name">div <span class="hljs-attr">style=<span class="hljs-string">{{ <span class="hljs-attr">...style, <span class="hljs-attr">opacity }}&gt;</span></span></span></span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">{name}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-tag">&lt;/<span class="hljs-name">div&gt;</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">);</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">export <span class="hljs-keyword">default Box;</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">复制代码</div>
</div>
</li>
</ol>
<h3>创建 Dustbin 组件,作为 DropTarget</h3>
<p>在&nbsp;<code>components</code>&nbsp;目录下,创建&nbsp;<code>Dustbin.js</code>&nbsp;文件,编写&nbsp;<code>Dustbin</code>&nbsp;组件,使其可以接受对应的拖拽组件。</p>
<p><code>components/Dustbin.js</code></p>
<ol class="hljs-ln">
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">import React <span class="hljs-keyword">from <span class="hljs-string">'react';</span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">import PropTypes <span class="hljs-keyword">from <span class="hljs-string">'prop-types';</span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">import { DropTarget } <span class="hljs-keyword">from <span class="hljs-string">'react-dnd';</span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">import ItemTypes <span class="hljs-keyword">from <span class="hljs-string">'../types';</span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">const style = {</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">height: <span class="hljs-string">'12rem',</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">width: <span class="hljs-string">'12rem',</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">marginRight: <span class="hljs-string">'1.5rem',</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">marginBottom: <span class="hljs-string">'1.5rem',</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">color: <span class="hljs-string">'white',</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">padding: <span class="hljs-string">'1rem',</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">textAlign: <span class="hljs-string">'center',</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">fontSize: <span class="hljs-string">'1rem',</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">lineHeight: <span class="hljs-string">'normal',</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">float: <span class="hljs-string">'left',</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">const boxTarget = {</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// 当有对应的 drag source 放在当前组件区域时,会返回一个对象,可以在 monitor.getDropResult() 中获取到</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">drop: <span class="hljs-function">() =&gt; ({ <span class="hljs-attr">name: <span class="hljs-string">'Dustbin' })</span></span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">@DropTarget(</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// type 标识,这里是字符串 'box'</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">ItemTypes.BOX,</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// 接收拖拽的事件对象</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">boxTarget,</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// 收集功能函数,包含 connect 和 monitor 参数</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// connect 里面的函数用来将 DOM 节点与 react-dnd 的 backend 建立联系</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-function">(<span class="hljs-params">connect, monitor) =&gt; ({</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// 包裹住 DOM 节点,使其可以接收对应的拖拽组件</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">connectDropTarget: connect.dropTarget(),</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// drag source是否在 drop target 区域</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">isOver: monitor.isOver(),</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// 是否可以被放置</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">canDrop: monitor.canDrop(),</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">})</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">)</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">Dustbin <span class="hljs-keyword">extends <span class="hljs-title">React.<span class="hljs-title">Component {</span></span></span></span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">static propTypes = {</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">canDrop: PropTypes.bool.isRequired,</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">isOver: PropTypes.bool.isRequired,</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-attr">connectDropTarget: PropTypes.func.isRequired</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">render() {</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">const { canDrop, isOver, connectDropTarget } = <span class="hljs-built_in">this.props;</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">const isActive = canDrop &amp;&amp; isOver;</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">let backgroundColor = <span class="hljs-string">'#222';</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// 拖拽组件此时正处于 drag target 区域时,当前组件背景色变为 darkgreen</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">if (isActive) {</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">backgroundColor = <span class="hljs-string">'darkgreen';</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// 当前组件可以放置 drag source 时,背景色变为 pink</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">else <span class="hljs-keyword">if (canDrop) {</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">backgroundColor = <span class="hljs-string">'darkkhaki';</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// 使用 connectDropTarget 包裹住 DOM 节点,使其可以接收对应的 drag source 组件</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// connectDropTarget 包裹住的 DOM 节点才能接收 drag source 组件</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">return connectDropTarget &amp;&amp; connectDropTarget(</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="xml">&lt;<span class="hljs-name">div <span class="hljs-attr">style=<span class="hljs-string">{{ <span class="hljs-attr">...style, <span class="hljs-attr">backgroundColor }}&gt;</span></span></span></span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">{isActive ? 'Release to drop' : 'Drag a box here'}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-tag">&lt;/<span class="hljs-name">div&gt;</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">);</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">export <span class="hljs-keyword">default Dustbin;</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">复制代码</div>
</div>
</li>
</ol>
<h3>在 App.js 文件中使用 DragDropContext</h3>
<p><code>App.js</code></p>
<ol class="hljs-ln">
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">import React, { Component } <span class="hljs-keyword">from <span class="hljs-string">'react';</span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">import { DragDropContext } <span class="hljs-keyword">from <span class="hljs-string">'react-dnd';</span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">import HTMLBackend <span class="hljs-keyword">from <span class="hljs-string">'react-dnd-html5-backend';</span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">import Dustbin <span class="hljs-keyword">from <span class="hljs-string">'./components/Dustbin';</span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">import Box <span class="hljs-keyword">from <span class="hljs-string">'./components/Box';</span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-comment">// 将 HTMLBackend 作为参数传给 DragDropContext</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">@DragDropContext(HTMLBackend)</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-class"><span class="hljs-keyword">class <span class="hljs-title">App <span class="hljs-keyword">extends <span class="hljs-title">Component {</span></span></span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">render() {</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">return (</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="xml">&lt;<span class="hljs-name">div <span class="hljs-attr">style=<span class="hljs-string">{{ <span class="hljs-attr">paddingLeft: <span class="hljs-attr">200, <span class="hljs-attr">paddingTop: <span class="hljs-attr">50 }}&gt;</span></span></span></span></span></span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-tag">&lt;<span class="hljs-name">div <span class="hljs-attr">style=<span class="hljs-string">{{ <span class="hljs-attr">overflow: '<span class="hljs-attr">hidden', <span class="hljs-attr">clear: '<span class="hljs-attr">both' }}&gt;</span></span></span></span></span></span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-tag">&lt;<span class="hljs-name">Box <span class="hljs-attr">name=<span class="hljs-string">"Glass" /&gt;</span></span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-tag">&lt;<span class="hljs-name">Box <span class="hljs-attr">name=<span class="hljs-string">"Banana" /&gt;</span></span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-tag">&lt;<span class="hljs-name">Box <span class="hljs-attr">name=<span class="hljs-string">"Paper" /&gt;</span></span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-tag">&lt;/<span class="hljs-name">div&gt;</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-tag">&lt;<span class="hljs-name">div <span class="hljs-attr">style=<span class="hljs-string">{{ <span class="hljs-attr">overflow: '<span class="hljs-attr">hidden', <span class="hljs-attr">clear: '<span class="hljs-attr">both' }}&gt;</span></span></span></span></span></span></span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-tag">&lt;<span class="hljs-name">Dustbin /&gt;</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-tag">&lt;/<span class="hljs-name">div&gt;</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-tag">&lt;/<span class="hljs-name">div&gt;</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">);</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">}</div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">&nbsp;</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line"><span class="hljs-keyword">export <span class="hljs-keyword">default App;</span></span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">复制代码</div>
</div>
</li>
</ol>
<h3>运行项目,查看效果</h3>
<p>运行项目:</p>
<ol class="hljs-ln">
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">$ npm run <span class="hljs-keyword">start</span></div>
</div>
</li>
<li>
<div class="hljs-ln-numbers">&nbsp;</div>
<div class="hljs-ln-code">
<div class="hljs-ln-line">复制代码</div>
</div>
</li>
</ol>
<p>浏览器会自动打开&nbsp;<code>http://localhost:3000/</code>&nbsp;窗口,此时可以操作浏览器上的 Box 组件,结合项目代码,查看效果。 预览效果如下:</p>
<p><img src="https://user-gold-cdn.xitu.io/2019/3/21/1699de2f67dcf1b0?imageslim" alt="预览效果" class="has"></p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<hr>
<h2>六、本文 Demo 地址</h2>
<p>react-dnd-dustbin</p>
<p>欢迎 Star!谢谢!</p>
<hr>
<h2>七、参考链接</h2>
<p>react-dnd 官方文档&nbsp;拖拽组件:React DnD 的使用</p>
<p><br>作者:暖生<br>链接:https://juejin.im/post/5c92e7fc6fb9a070e5529322<br>来源:掘金<br>著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。</p>

</div>
<div id="MySignature" role="contentinfo">
    漫思<br><br>
来源:https://www.cnblogs.com/sexintercourse/p/14851510.html
頁: [1]
查看完整版本: react-dnd 用法详解