react-beautiful-dnd 實(shí)現(xiàn)組件拖拽

一個(gè)React.js 的 漂亮,可移植性 列表拖拽庫跟继。想了解更多react-beautiful-dnd特點(diǎn)適用人群請看 官方文檔落萎、 中文翻譯文檔

1.安裝

? 在已有react項(xiàng)目中 執(zhí)行以下命令 so easy伐脖。

# yarn
yarn add react-beautiful-dnd

# npm
npm install react-beautiful-dnd --save

2.APi

詳情查看 官方文檔汗捡。

3.react-beautiful-dnd demo

3.1 demo1 縱向組件拖拽

效果下圖:
demo1.gif

實(shí)現(xiàn)代碼:

import React, { Component } from "react";
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";

//初始化數(shù)據(jù)
const getItems = count =>
  Array.from({ length: count }, (v, k) => k).map(k => ({
    id: `item-${k + 1}`,
    content: `this is content ${k + 1}`
  }));

// 重新記錄數(shù)組順序
const reorder = (list, startIndex, endIndex) => {
  const result = Array.from(list);

  const [removed] = result.splice(startIndex, 1);

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

const grid = 8;

// 設(shè)置樣式
const getItemStyle = (isDragging, draggableStyle) => ({
  // some basic styles to make the items look a bit nicer
  userSelect: "none",
  padding: grid * 2,
  margin: `0 0 ${grid}px 0`,

  // 拖拽的時(shí)候背景變化
  background: isDragging ? "lightgreen" : "#ffffff",

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

const getListStyle = () => ({
  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 (
      <DragDropContext onDragEnd={this.onDragEnd}>
        <center>
          <Droppable droppableId="droppable">
            {(provided, snapshot) => (
              <div
              //provided.droppableProps應(yīng)用的相同元素.
                {...provided.droppableProps}
                // 為了使 droppable 能夠正常工作必須 綁定到最高可能的DOM節(jié)點(diǎn)中provided.innerRef.
                ref={provided.innerRef}
                style={getListStyle(snapshot)}
              >
                {this.state.items.map((item, index) => (
                  <Draggable key={item.id} draggableId={item.id} index={index}>
                    {(provided, snapshot) => (
                      <div
                        ref={provided.innerRef}
                        {...provided.draggableProps}
                        {...provided.dragHandleProps}
                        style={getItemStyle(
                          snapshot.isDragging,
                          provided.draggableProps.style
                        )}
                      >
                        {item.content}
                      </div>
                    )}
                  </Draggable>
                ))}
                {provided.placeholder}
              </div>
            )}
          </Droppable>
        </center>
      </DragDropContext>
    );
  }
}


3.2 demo2 水平拖拽

? 效果下圖:
demo2.gif

實(shí)現(xiàn)代碼: 其實(shí)和縱向拖拽差不多 Droppable 中 多添加了一個(gè)排列順序的屬性,direction="horizontal"

import React, { Component } from "react";
import { DragDropContext, Droppable, Draggable } from "react-beautiful-dnd";


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

// 重新記錄數(shù)組順序
const reorder = (list, startIndex, endIndex) => {
  const result = Array.from(list);
  //刪除并記錄 刪除元素
  const [removed] = result.splice(startIndex, 1);
  //將原來的元素添加進(jìn)數(shù)組
  result.splice(endIndex, 0, removed);
  return result;
};

const grid = 8;


// 設(shè)置樣式
const getItemStyle = (isDragging, draggableStyle) => ({
  // some basic styles to make the items look a bit nicer
  userSelect: "none",
  padding: grid * 2,
  margin: `0 ${grid}px 0 0 `,

  // 拖拽的時(shí)候背景變化
  background: isDragging ? "lightgreen" : "#ffffff",

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

const getListStyle = () => ({
  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 (
      <DragDropContext onDragEnd={this.onDragEnd}>
        <Droppable droppableId="droppable" direction="horizontal">
          {(provided, snapshot) => (
            <div
              {...provided.droppableProps}
              ref={provided.innerRef}
              style={getListStyle(snapshot.isDraggingOver)}
            >
              {this.state.items.map((item, index) => (
                <Draggable key={item.id} draggableId={item.id} index={index}>
                  {(provided, snapshot) => (
                    <div
                      ref={provided.innerRef}
                      {...provided.draggableProps}
                      {...provided.dragHandleProps}
                      style={getItemStyle(
                        snapshot.isDragging,
                        provided.draggableProps.style
                      )}
                    >
                      {item.content}
                    </div>
                  )}
                </Draggable>
              ))}
              {provided.placeholder}
            </div>
          )}
        </Droppable>
      </DragDropContext>
    )
  }
}

export default ReactBeautifulDndHorizontal

3.3 demo3實(shí)現(xiàn)一個(gè)代辦事項(xiàng)的拖拽(縱向 橫向拖拽)

demo3.gif

實(shí)現(xiàn)原理其實(shí)大同小異 奔穿。代碼整理后放在github上豹休。地址:github
)

4.感受

目前簡單的使用react - beautiful-dnd下來感覺 炊昆,上手感覺挺簡單,api也不繁瑣威根。性能也不錯(cuò)(demo2中做過渲染170多個(gè)task凤巨。拖拽起來還是如絲般順滑)。日后遇到啥不足會(huì)mark在一下洛搀。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末敢茁,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子留美,更是在濱河造成了極大的恐慌彰檬,老刑警劉巖伸刃,帶你破解...
    沈念sama閱讀 219,589評(píng)論 6 508
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異逢倍,居然都是意外死亡捧颅,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,615評(píng)論 3 396
  • 文/潘曉璐 我一進(jìn)店門较雕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來碉哑,“玉大人,你說我怎么就攤上這事亮蒋】鄣洌” “怎么了?”我有些...
    開封第一講書人閱讀 165,933評(píng)論 0 356
  • 文/不壞的土叔 我叫張陵慎玖,是天一觀的道長激捏。 經(jīng)常有香客問我,道長凄吏,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,976評(píng)論 1 295
  • 正文 為了忘掉前任闰蛔,我火速辦了婚禮痕钢,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘序六。我一直安慰自己任连,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,999評(píng)論 6 393
  • 文/花漫 我一把揭開白布例诀。 她就那樣靜靜地躺著随抠,像睡著了一般。 火紅的嫁衣襯著肌膚如雪繁涂。 梳的紋絲不亂的頭發(fā)上拱她,一...
    開封第一講書人閱讀 51,775評(píng)論 1 307
  • 那天背蟆,我揣著相機(jī)與錄音擎椰,去河邊找鬼。 笑死辕狰,一個(gè)胖子當(dāng)著我的面吹牛矿酵,可吹牛的內(nèi)容都是我干的唬复。 我是一名探鬼主播,決...
    沈念sama閱讀 40,474評(píng)論 3 420
  • 文/蒼蘭香墨 我猛地睜開眼全肮,長吁一口氣:“原來是場噩夢啊……” “哼敞咧!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起辜腺,我...
    開封第一講書人閱讀 39,359評(píng)論 0 276
  • 序言:老撾萬榮一對(duì)情侶失蹤休建,失蹤者是張志新(化名)和其女友劉穎乍恐,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體丰包,經(jīng)...
    沈念sama閱讀 45,854評(píng)論 1 317
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡禁熏,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,007評(píng)論 3 338
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了邑彪。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瞧毙。...
    茶點(diǎn)故事閱讀 40,146評(píng)論 1 351
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖寄症,靈堂內(nèi)的尸體忽然破棺而出宙彪,到底是詐尸還是另有隱情,我是刑警寧澤有巧,帶...
    沈念sama閱讀 35,826評(píng)論 5 346
  • 正文 年R本政府宣布释漆,位于F島的核電站,受9級(jí)特大地震影響篮迎,放射性物質(zhì)發(fā)生泄漏男图。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,484評(píng)論 3 331
  • 文/蒙蒙 一甜橱、第九天 我趴在偏房一處隱蔽的房頂上張望逊笆。 院中可真熱鬧,春花似錦岂傲、人聲如沸难裆。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,029評(píng)論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽乃戈。三九已至,卻和暖如春亩进,著一層夾襖步出監(jiān)牢的瞬間症虑,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,153評(píng)論 1 272
  • 我被黑心中介騙來泰國打工归薛, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留侦讨,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,420評(píng)論 3 373
  • 正文 我出身青樓苟翻,卻偏偏與公主長得像韵卤,于是被迫代替她去往敵國和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子崇猫,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,107評(píng)論 2 356

推薦閱讀更多精彩內(nèi)容