红山牛 發表於 2020-7-14 14:44:00

【React】react-beautiful-dnd 实现组件拖拽

<p>一个React.js 的 漂亮,可移植性 列表拖拽库。想了解更多react-beautiful-dnd特点适用人群请看&nbsp;官方文档、&nbsp;中文翻译文档</p>
<p>npm:https://www.npmjs.com/package/react-beautiful-dnd</p>
<div>
<div>
<h2>.安装</h2>
<p>​ 在已有react项目中 执行以下命令 so easy。</p>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;"># yarn
yarn add react-beautiful-dnd

# npm
npm install react-beautiful-dnd --save</pre>
</div>
</div>
<h2>2.APi</h2>
<p>详情查看 官方文档。</p>
<h2>3.react-beautiful-dnd demo</h2>
<h3>3.1 demo1 纵向组件拖拽</h3>
<p>&nbsp;</p>
<p>&nbsp;</p>
效果下图:
<div class="image-package">
<div class="image-container">
<div class="image-container-fill">&nbsp;</div>
<div class="image-view" data-width="653" data-height="696"><img src="//upload-images.jianshu.io/upload_images/19417372-25b45bcd5ddf1de4.gif?imageMogr2/auto-orient/strip|imageView2/2/w/653/format/webp"></div>
</div>
<div class="image-caption">demo1.gif</div>
</div>
<p>实现代码:</p>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;">import React, { Component } from "react";
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";

//初始化数据
const getItems = count =&gt;
Array.from({ length: count }, (v, k) =&gt; k).map(k =&gt; ({
    id: `item-${k + 1}`,
    content: `this is content ${k + 1}`
}));

// 重新记录数组顺序
const reorder = (list, startIndex, endIndex) =&gt; {
const result = Array.from(list);

const = result.splice(startIndex, 1);

result.splice(endIndex, 0, removed);
return result;
};

const grid = 8;

// 设置样式
const getItemStyle = (isDragging, draggableStyle) =&gt; ({
// some basic styles to make the items look a bit nicer
userSelect: "none",
padding: grid * 2,
margin: `0 0 ${grid}px 0`,

// 拖拽的时候背景变化
background: isDragging ? "lightgreen" : "#ffffff",

// styles we need to apply on draggables
...draggableStyle
});

const getListStyle = () =&gt; ({
background: 'black',
padding: grid,
width: 250
});



export default class ReactBeautifulDnd extends Component {
constructor(props) {
    super(props);
    this.state = {
      items: getItems(11)
    };
    this.onDragEnd = this.onDragEnd.bind(this);
}

onDragEnd(result) {
    if (!result.destination) {
      return;
    }

    const items = reorder(
      this.state.items,
      result.source.index,
      result.destination.index
    );

    this.setState({
      items
    });
}


render() {
    return (
      &lt;DragDropContext onDragEnd={this.onDragEnd}&gt;
      &lt;center&gt;
          &lt;Droppable droppableId="droppable"&gt;
            {(provided, snapshot) =&gt; (
            &lt;div
            //provided.droppableProps应用的相同元素.
                {...provided.droppableProps}
                // 为了使 droppable 能够正常工作必须 绑定到最高可能的DOM节点中provided.innerRef.
                ref={provided.innerRef}
                style={getListStyle(snapshot)}
            &gt;
                {this.state.items.map((item, index) =&gt; (
                  &lt;Draggable key={item.id} draggableId={item.id} index={index}&gt;
                  {(provided, snapshot) =&gt; (
                      &lt;div
                        ref={provided.innerRef}
                        {...provided.draggableProps}
                        {...provided.dragHandleProps}
                        style={getItemStyle(
                        snapshot.isDragging,
                        provided.draggableProps.style
                        )}
                      &gt;
                        {item.content}
                      &lt;/div&gt;
                  )}
                  &lt;/Draggable&gt;
                ))}
                {provided.placeholder}
            &lt;/div&gt;
            )}
          &lt;/Droppable&gt;
      &lt;/center&gt;
      &lt;/DragDropContext&gt;
    );
}
}
</pre>
</div>
<p>  </p>
</div>
<h3>3.2 demo2 水平拖拽</h3>
<p>&nbsp;</p>
<p>&nbsp;</p>
​ 效果下图:
<div class="image-package">
<div class="image-container">
<div class="image-container-fill">&nbsp;</div>
<div class="image-view" data-width="1128" data-height="288"><img src="//upload-images.jianshu.io/upload_images/19417372-3906d8743b1f4470.gif?imageMogr2/auto-orient/strip|imageView2/2/w/1128/format/webp"></div>
</div>
<div class="image-caption">demo2.gif</div>
</div>
<p>实现代码: 其实和纵向拖拽差不多 Droppable 中 多添加了一个排列顺序的属性,direction="horizontal"</p>
<div class="_2Uzcx_"><button class="VJbwyy" type="button"></button>
<div class="cnblogs_Highlighter">
<pre class="brush:javascript;gutter:true;">import React, { Component } from "react";
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";


const getItems = count =&gt; (
Array.from({ length: count }, (v, k) =&gt; k).map(k =&gt; ({
    id: `item-${k + 1}`,
    content: `this is content ${k + 1}`
}))
)

// 重新记录数组顺序
const reorder = (list, startIndex, endIndex) =&gt; {
const result = Array.from(list);
//删除并记录 删除元素
const = result.splice(startIndex, 1);
//将原来的元素添加进数组
result.splice(endIndex, 0, removed);
return result;
};

const grid = 8;


// 设置样式
const getItemStyle = (isDragging, draggableStyle) =&gt; ({
// some basic styles to make the items look a bit nicer
userSelect: "none",
padding: grid * 2,
margin: `0 ${grid}px 0 0 `,

// 拖拽的时候背景变化
background: isDragging ? "lightgreen" : "#ffffff",

// styles we need to apply on draggables
...draggableStyle
});

const getListStyle = () =&gt; ({
background: 'black',
display: 'flex',
padding: grid,
overflow: 'auto',
});


class ReactBeautifulDndHorizontal extends Component {
constructor(props) {
    super(props);
    this.state = {
      items: getItems(10)
    };
    this.onDragEnd = this.onDragEnd.bind(this);
}

onDragEnd(result) {
    if (!result.destination) {
      return;
    }

    const items = reorder(
      this.state.items,
      result.source.index,
      result.destination.index
    );

    this.setState({
      items
    });
}

render() {
    return (
      &lt;DragDropContext onDragEnd={this.onDragEnd}&gt;
      &lt;Droppable droppableId="droppable" direction="horizontal"&gt;
          {(provided, snapshot) =&gt; (
            &lt;div
            {...provided.droppableProps}
            ref={provided.innerRef}
            style={getListStyle(snapshot.isDraggingOver)}
            &gt;
            {this.state.items.map((item, index) =&gt; (
                &lt;Draggable key={item.id} draggableId={item.id} index={index}&gt;
                  {(provided, snapshot) =&gt; (
                  &lt;div
                      ref={provided.innerRef}
                      {...provided.draggableProps}
                      {...provided.dragHandleProps}
                      style={getItemStyle(
                        snapshot.isDragging,
                        provided.draggableProps.style
                      )}
                  &gt;
                      {item.content}
                  &lt;/div&gt;
                  )}
                &lt;/Draggable&gt;
            ))}
            {provided.placeholder}
            &lt;/div&gt;
          )}
      &lt;/Droppable&gt;
      &lt;/DragDropContext&gt;
    )
}
}

export default ReactBeautifulDndHorizontal
</pre>
</div>
<p>  </p>
</div>
<h3>3.3 demo3实现一个代办事项的拖拽(纵向 横向拖拽)</h3>
<div class="image-package">
<div class="image-container">
<div class="image-container-fill">&nbsp;</div>
<div class="image-view" data-width="1128" data-height="344"><img src="//upload-images.jianshu.io/upload_images/19417372-af64654e18862dca.gif?imageMogr2/auto-orient/strip|imageView2/2/w/1128/format/webp"></div>
</div>
<div class="image-caption">demo3.gif</div>
</div>
<p>实现原理其实大同小异 。代码整理后放在github上。地址:github<br>)</p>
<h2>4.感受</h2>
<p>目前简单的使用react - beautiful-dnd下来感觉 ,上手感觉挺简单,api也不繁琐。性能也不错(demo2中做过渲染170多个task。拖拽起来还是如丝般顺滑)。日后遇到啥不足会mark在一下。</p>
<div>&nbsp;</div>

</div>

链接:https://www.jianshu.com/p/ba19292cdc7e<br>来源:简书</div><br><br>
来源:https://www.cnblogs.com/Ewarm/p/13299009.html
頁: [1]
查看完整版本: 【React】react-beautiful-dnd 实现组件拖拽