SunXinFei / sunxinfei.github.io

前后端技术相关笔记,已迁移到 Issues 中
https://github.com/SunXinFei/sunxinfei.github.io/issues
32 stars 3 forks source link

React DnD 中文 #8

Open SunXinFei opened 6 years ago

SunXinFei commented 6 years ago

DragSource

import { DragSource } from 'react-dnd';

class MyComponent {
  /* ... */
}

export default DragSource(type, spec, collect)(MyComponent);//DragSource相当于装饰器

DragSource(type, spec, collect)的参数解读

  1. type :Required. Either a string, an ES6 symbol, or a function that returns either given the component's props. Only the drop targets registered for the same type will react to the items produced by this drag source. Read the overview to learn more about the items and types. 必须,设置好跟dropTarget相同的type字符串,才能够放置。

  2. spec: Required. A plain JavaScript object with a few allowed methods on it. It describes how the drag source reacts to the drag and drop events. See the drag source specification described in detail in the next section. 必须,一个js对象,里面有一些拖拽相关的方法。

    关于spec中的方法:

    • beginDrag(props, monitor, component): Required. When the dragging starts, beginDrag is called. You must return a plain JavaScript object describing the data being dragged. What you return is the only information available to the drop targets about the drag source so it's important to pick the minimal data they need to know. You may be tempted to put a reference to the component into it, but you should try very hard to avoid doing this because it couples the drag sources and drop targets. It's a good idea to return something like { id: props.id } from this method. 必须,当拖拽开始时,beginDrag将会被调用,必须在该方法中return一个js对象,这样drop的spec中monitor.getItem()才能拿到,推荐return 一个数据对象如 { id: props.id } 。
    • endDrag(props, monitor, component): Optional. When the dragging stops, endDrag is called. For every beginDrag call, a corresponding endDrag call is guaranteed. You may call monitor.didDrop() to check whether or not the drop was handled by a compatible drop target. If it was handled, and the drop target specified a drop result by returning a plain object from its drop() method, it will be available as monitor.getDropResult(). This method is a good place to fire a Flux action. Note: If the component is unmounted while dragging, component parameter is set to be null. 可选,当拖拽事件停止时,endDrag将会被调用,一个beginDrag调用就会对应一个endDrag调用。
    • canDrag(props, monitor): Optional. Use it to specify whether the dragging is currently allowed. If you want to always allow it, just omit this method. Specifying it is handy if you'd like to disable dragging based on some predicate over props. Note: You may not call monitor.canDrag() inside this method.可选,是否允许被拖拽,如果一直是允许的,可以忽略该方法。注意不能在此方法内调用monitor.canDrag()
    • isDragging(props, monitor): Optional. By default, only the drag source that initiated the drag operation is considered to be dragging. You can override this behavior by defining a custom isDragging method. It might return something like props.id === monitor.getItem().id. Do this if the original component may be unmounted during the dragging and later “resurrected” with a different parent. For example, when moving a card across the lists in a Kanban board, you want it to retain the dragged appearance—even though technically, the component gets unmounted and a different one gets mounted every time you move it to another list. Note: You may not call monitor.isDragging() inside this method.可选,注意不能在此方法内调用monitor.isDragging()
    • 关于spec方法中的参数

    • props: _Your component's current props. 当前组件的props
    • monitor: An instance of DragSourceMonitor. Use it to query the information about the current drag state, such as the currently dragged item and its type, the current and initial coordinates and offsets, and whether it was dropped yet. Read the DragSourceMonitor documentation for a complete list of monitor methods, or read the overview for an introduction to the monitors. DragSourceMonitor的实例,用来获取一些当前拖拽的状态,例如当前拖拽的项目,类型,坐标和便宜,是否drop。
    • component: When specified, it is the instance of your component. Use it to access the underlying DOM node for position or size measurements, or to call setState, and other component methods. It is purposefully missing from isDragging and canDrag because the instance may not be available by the time they are called. If you want these methods to depend on the component's state, consider lifting the state to the parent component, so that you can just use props. Generally your code will be cleaner if you rely on props instead whenever possible. 尽可能的使用props而不是component,代码将会变得很清晰,
  3. collect: Required. The collecting function. It should return a plain object of the props to inject into your component. It receives two parameters: connect and monitor. Read the overview for an introduction to the monitors, the connectors, and the collecting function. See the collecting function described in detail after the next section. 必须,collect方法有两个参数connect和monitor

  4. options: Optional. A plain object. If some of the props to your component are not scalar (that is, are not primitive values or functions), specifying a custom arePropsEqual(props, otherProps) function inside the options object can improve the performance. Unless you have performance problems, don't worry about it. 可选的参数,如果有性能问题才需要关心。

Monitor一些公共方法的表示的值

  1. getInitialClientOffset() :Returns the { x, y } client offset of the pointer at the time when the current drag operation has started. Returns null if no item is being dragged. 表示鼠标指针的在拖拽操作开始时的xy坐标,浏览器可视范围内的,不考虑滚动条,浏览器可视范围的左上角为(0,0)。
  2. getInitialSourceClientOffset():Returns the { x, y } client offset of the drag source component's root DOM node at the time when the current drag operation has started. Returns null if no item is being dragged. 表示拖拽的当面DOM在拖动操作开始时的xy坐标,在浏览器可视范围内的,不考虑滚动条,浏览器可视范围的左上角为(0,0)。
  3. getClientOffset(): Returns the last recorded { x, y } client offset of the pointer while a drag operation is in progress. Returns null if no item is being dragged. 表示拖拽中鼠标指针的xy坐标,在浏览器可视范围内的, 不考虑滚动条,浏览器可视范围的左上角为(0,0)。
  4. getDifferenceFromInitialOffset(): Returns the { x, y } difference between the last recorded client offset of the pointer and the client offset when current the drag operation has started. Returns null if no item is being dragged. 拖拽的DOM相对于自身之前所在位置的偏移。完全重合为(0,0)。
  5. getSourceClientOffset(): Returns the projected { x, y } client offset of the drag source component's root DOM node, based on its position at the time when the current drag operation has started, and the movement difference. Returns null if no item is being dragged. 拖拽的DOM在拖动操作中的xy坐标,放置到可视范围内的左上角为(0,0),不考虑滚动条
SunXinFei commented 5 years ago

单页面两个DragDropContext报错的问题

按照react-dnd的issue中封装一个context类,调用该类即可

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

export default DragDropContext(HTML5Backend);

dragPreview的问题

如果自定义了dragPreview,取消掉默认的浏览器preview就需要添加getEmptyImage

import { getEmptyImage } from 'react-dnd-html5-backend';
componentDidMount() {
  // Use empty image as a drag preview so browsers don't draw it
  // and we can draw whatever we want on the custom drag layer instead.
  this.props.connectDragPreview(getEmptyImage(), {
    // IE fallback: specify that we'd rather screenshot the node
    // when it already knows it's being dragged so we can hide it with CSS.
    captureDraggingState: true
  });
}
SunXinFei commented 4 years ago

React-dnd V9.3.9

React-dnd更新版本迭代时隔一年已经升级了N个版本,迭代升级速度让我非常吃惊,于是最新项目,我们使用v9.3.9版本去开发,看看跟之前的代码变化。