React 拖拽排序

這篇文章基本骨架來(lái)自:文件點(diǎn)擊上傳和拖拽上傳

今天我們要解決的問(wèn)題就是頁(yè)面上我們上傳了多個(gè)文件,我們需要怎么實(shí)現(xiàn)移動(dòng)拖拽排序的效果溺欧。

借用插件笔喉,先安裝:

npm install --save react-sortable

參考官方文檔:https://www.npmjs.com/package/react-sortable
實(shí)現(xiàn)效果:

拖拽排序

思路:

  • 要求每個(gè)圖片必須是一個(gè)單獨(dú)的組件
    圖片組件配置一共三步:
import React, { Component } from 'react'
// ①引包
import {sortable} from "react-sortable";
// ②裝飾器語(yǔ)法進(jìn)行組件裝飾,注意這個(gè)裝飾器就一個(gè)圓括號(hào)
// ③根 div 加上{...this.props}
@sortable
export default class Sortable extends Component {
    render() {
        return (
            <div className = "cur" {...this.props}>
                <img src = {this.props.base64}/>
            </div>
        )
    }
}

如果不使用@這個(gè)語(yǔ)法糖就得這樣寫(xiě):

import React, { Component } from 'react'
// ①引包
import {sortable} from "react-sortable";
// ③根 div 加上{...this.props}

class Sortable extends Component {
    render() {
        return (
            <div className = "cur" {...this.props}>
                <img src = {this.props.base64}/>
            </div>
        )
    }
}
// ②裝飾器語(yǔ)法進(jìn)行組件裝飾糠惫,注意這個(gè)裝飾器就一個(gè)圓括號(hào)
export default sortable(Sortable)

到這里拖拽圖片的話(huà)基本就可看見(jiàn)拖拽效果实撒,但是還不能看到排序的效果遵蚜。

  • 父組件也得三步操作,操作的地方就在子組件上
{
    this.state.base64.map((item,index) => <Sortable key = {index} base64 = {item} 
    onSortItems={(arr)=>{
        this.setState({
            base64:arr
        })
    }}
    items={this.state.base64}
    sortId={index}
    />)
}

第一個(gè)地方:給子組件一個(gè) sortId 一般 key 用啥就給它啥
第二個(gè)地方:items 給它的值就是當(dāng)前進(jìn)行 map 的數(shù)組
第三個(gè)地方:一個(gè)函數(shù)奈惑,很明顯是使用排序好的數(shù)組來(lái)更新當(dāng)前數(shù)組

沒(méi)啦配置完成。

以下是 2019年08月29日的補(bǔ)充

二睡汹、react 拖拽的進(jìn)化

上面的拖拽是非常的簡(jiǎn)單肴甸,特別像我以前使用原生 JS 模仿簡(jiǎn)書(shū)后臺(tái)寫(xiě)的一個(gè)九宮格拖拽。這種有一個(gè)缺點(diǎn)囚巴,沒(méi)有動(dòng)畫(huà)原在,在重視用戶(hù)體驗(yàn)的情況下,這種插件是萬(wàn)萬(wàn)不能用的彤叉。其實(shí)實(shí)現(xiàn)動(dòng)畫(huà)原理也特別的簡(jiǎn)單庶柿,再源碼在加個(gè)動(dòng)畫(huà)延遲就行了。今天在看 react-sortable npm 官網(wǎng)的時(shí)候秽浇,發(fā)現(xiàn)它推薦了兩個(gè)動(dòng)畫(huà)特別流暢的 npm 包浮庐。react-sortable-hocreact-beautiful-dnd 。隨便選一個(gè)用一下柬焕,react-sortable-hoc的下載量高一點(diǎn)就用它了审残。開(kāi)始:

  • 安裝兩個(gè)插件
npm install --save react-sortable-hoc
npm install --save array-move

先解釋第二個(gè):
array-move 就一個(gè) API,它的主要作用就是用來(lái)交換數(shù)組中元素的位置斑举。我們用 node 進(jìn)行調(diào)試 1.js 文件搅轿,調(diào)試結(jié)果如下:

// 引包
const arrayMove = require('array-move');
// 創(chuàng)建一個(gè)數(shù)組
const input = ['a', 'b', 'c'];
 
// 以下三個(gè)排序?qū)嵗?console.log(arrayMove(input, 1, 2));
//=> ['a', 'c', 'b']
 
console.log(arrayMove(input, -1, 0));
//=> ['c', 'a', 'b']
 
console.log(arrayMove(input, -2, -3));
//=> ['b', 'a', 'c']

node 1.js 運(yùn)行文件,控制臺(tái)輸出結(jié)果如下:

C:\Users\Administrator\Desktop\my>node 1.js
[ 'a', 'c', 'b' ]
[ 'c', 'a', 'b' ]
[ 'b', 'a', 'c' ]
  • 高階函數(shù)
    在熟練使用 react-sortable-hoc 之前富玷,先熟悉高階函數(shù)璧坟。

高階函數(shù)的定義簡(jiǎn)單來(lái)講就是:高階函數(shù)(Higher Order Function)=> 參數(shù)或返回值為函數(shù)

我們常見(jiàn)的有數(shù)組的遍歷方式 Map赎懦、Reduce雀鹃、Filter、Sort铲敛;常用的 redux 中的 connect 方法也是高階函數(shù)褐澎。

這里在補(bǔ)充一個(gè)專(zhuān)有名詞:函數(shù)的 柯里化

維基百科上:Currying(柯里化)是把接受多個(gè)參數(shù)的函數(shù)變換成接受一個(gè)單一參數(shù)(最初函數(shù)的第一個(gè)參數(shù))的函數(shù),并且返回接受余下的參數(shù)而且返回結(jié)果的新函數(shù)的技術(shù)伐蒋。

說(shuō)白了就是一個(gè)函數(shù)調(diào)用的時(shí)候形參至少多余一個(gè)工三,柯里化就是在保證函數(shù)功能不變的情況下迁酸,把函數(shù)調(diào)用的形參限定只能是一個(gè)。

看一個(gè)簡(jiǎn)單加法器的案例:

//普通加法函數(shù)
function add(x,y){
    return x + y;
}
add(8,9);

// 柯里化
function add(x){
    // x這里屬于閉包的概念
    return function(y){
        return x + y;
    }
}
add(8)(9);

這玩意有啥用那俭正,有函數(shù)不就行了奸鬓?

可以提高函數(shù)的復(fù)用,例如一個(gè)字符串多次進(jìn)行不同類(lèi)型的正則查詢(xún)掸读。這個(gè)過(guò)程又有一個(gè)概念叫預(yù)處理串远。

請(qǐng)看演示:

// 正常正則驗(yàn)證字符串 reg.test(txt)

// 函數(shù)封裝后
function check(reg, txt) {
    return reg.test(txt)
}

check(/\d+/g, 'abc')       //false
check(/[a-z]+/g, 'abc')    //true

// 柯里化
function curryingCheck(txt) {
    return function(reg) {
        return reg.test(txt)
    }
}

let has = curryingCheck("從我a1b2c3d4ef里面篩選只篩選出數(shù)字或字母!");
// 柯里化不像普通函數(shù)一樣老是需要傳入形參txt
has(/\d+/g); //true
has(/[a-z]/g)//true
  • react-sortable-hoc 使用
    react-sortable-hoc 提供了兩個(gè)特別重要的 API 儿惫,分別是SortableContainer 和 SortableElement 看英文的意思也知道澡罚,SortableElement用來(lái)裝飾每個(gè)要拖拽的組件,相對(duì)于SortableContainer 要裝飾的組件肾请,SortableElement 裝飾的組件是子組件留搔。

  • SortableElement 提供了一個(gè) index 屬性來(lái)進(jìn)行子組件排序。

  • SortableContainer 提供一個(gè)方法 onSortEnd 铛铁。這個(gè)函數(shù)可以結(jié)構(gòu)兩個(gè)形參隔显。{oldIndex, newIndex} 一個(gè)是拖拽元素的標(biāo)記,一個(gè)是將要放的那個(gè)地方標(biāo)記饵逐。最后在使用 arrayMove 交換數(shù)組的位置括眠。axis 是拖拽的方向,默認(rèn)是 y 倍权,垂直拖拽掷豺,x 表示只可以水平拖拽。

搞清楚這些上案例:
文件夾的邏輯結(jié)構(gòu)就是 App.js 請(qǐng)求數(shù)據(jù)薄声,數(shù)據(jù)是個(gè)數(shù)組傳給子組件 B (用SortableContainer裝飾)萌业,孫子組件 A 來(lái)呈現(xiàn)圖片(用SortableElement裝飾),另外本案例使用了語(yǔ)法糖@SortableContainer 完全可以替換為 SortableContainer(組件)

父組件:App.js

import React, { Component } from 'react';
import B from "./B";
import { SortableContainer } from 'react-sortable-hoc';
import arrayMove from 'array-move';
import axios from "axios";
export default class App extends Component {
    constructor(){
        super();
        this.state = {
            arr : [105,106,107]
        }
    }
    render() {
        this.onSortEnd = ({oldIndex, newIndex}) => {
            this.setState({
                arr: arrayMove(this.state.arr, oldIndex, newIndex)
            });
        };
        return (
            <div>
                <B arr={this.state.arr} axis="x" onSortEnd={this.onSortEnd}/>
            </div>
        )
    }
}

子組件 B.js

import React, { Component } from 'react';
import A from "./A";
import { SortableContainer } from 'react-sortable-hoc';
@SortableContainer
export default class B extends Component {
    constructor(){
        super();
    }
    render() {
        return (
            <div>
                {this.props.arr.map((item,index)=><A collection="沙雕" key={item} item={item} index={index} onSortEnd={this.onSortEnd}/>)}
            </div>
        )
    }
}

孫子組件A.js:

import React, { Component } from 'react';
import { sortableElement } from 'react-sortable-hoc';
@sortableElement
export default class A extends Component {
    constructor(){
        super();
    }
    render() {
        return (
            <div style={{"float":"left"}}>
                {<img src={`./images/${this.props.item}.jpg`}/>}
            </div>
        )
    }
}

運(yùn)行效果:


react-sortable-hoc
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末奸柬,一起剝皮案震驚了整個(gè)濱河市生年,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌廓奕,老刑警劉巖抱婉,帶你破解...
    沈念sama閱讀 206,311評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異桌粉,居然都是意外死亡蒸绩,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評(píng)論 2 382
  • 文/潘曉璐 我一進(jìn)店門(mén)铃肯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)患亿,“玉大人,你說(shuō)我怎么就攤上這事〔脚海” “怎么了惦界?”我有些...
    開(kāi)封第一講書(shū)人閱讀 152,671評(píng)論 0 342
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)咙冗。 經(jīng)常有香客問(wèn)我沾歪,道長(zhǎng),這世上最難降的妖魔是什么雾消? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,252評(píng)論 1 279
  • 正文 為了忘掉前任灾搏,我火速辦了婚禮,結(jié)果婚禮上立润,老公的妹妹穿的比我還像新娘狂窑。我一直安慰自己,他們只是感情好桑腮,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,253評(píng)論 5 371
  • 文/花漫 我一把揭開(kāi)白布蕾域。 她就那樣靜靜地躺著,像睡著了一般到旦。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上巨缘,一...
    開(kāi)封第一講書(shū)人閱讀 49,031評(píng)論 1 285
  • 那天添忘,我揣著相機(jī)與錄音,去河邊找鬼若锁。 笑死搁骑,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的又固。 我是一名探鬼主播仲器,決...
    沈念sama閱讀 38,340評(píng)論 3 399
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼仰冠!你這毒婦竟也來(lái)了乏冀?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 36,973評(píng)論 0 259
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤洋只,失蹤者是張志新(化名)和其女友劉穎辆沦,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體识虚,經(jīng)...
    沈念sama閱讀 43,466評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡肢扯,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 35,937評(píng)論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了担锤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片蔚晨。...
    茶點(diǎn)故事閱讀 38,039評(píng)論 1 333
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖肛循,靈堂內(nèi)的尸體忽然破棺而出铭腕,到底是詐尸還是另有隱情银择,我是刑警寧澤,帶...
    沈念sama閱讀 33,701評(píng)論 4 323
  • 正文 年R本政府宣布谨履,位于F島的核電站欢摄,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏笋粟。R本人自食惡果不足惜怀挠,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,254評(píng)論 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望害捕。 院中可真熱鬧绿淋,春花似錦、人聲如沸尝盼。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,259評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)盾沫。三九已至裁赠,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間赴精,已是汗流浹背佩捞。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,485評(píng)論 1 262
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留蕾哟,地道東北人一忱。 一個(gè)月前我還...
    沈念sama閱讀 45,497評(píng)論 2 354
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像谭确,于是被迫代替她去往敵國(guó)和親帘营。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,786評(píng)論 2 345

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

  • 深入JSX date:20170412筆記原文其實(shí)JSX是React.createElement(componen...
    gaoer1938閱讀 8,048評(píng)論 2 35
  • 今天的React題沒(méi)有太多的故事…… 半個(gè)月前出了248個(gè)Vue的知識(shí)點(diǎn)逐哈,受到很多朋友的關(guān)注芬迄,都強(qiáng)烈要求再出多些R...
    浪子神劍閱讀 10,067評(píng)論 6 106
  • 探索Vue高階組件 高階組件(HOC)是 React 生態(tài)系統(tǒng)的常用詞匯,React 中代碼復(fù)用的主要方式就是使用...
    君惜丶閱讀 963評(píng)論 0 2
  • 鐘悅悅一開(kāi)始并不是做HR的昂秃,以前每次找工作薯鼠,去到每一家公司,前臺(tái)美女都讓她填《應(yīng)聘登記表》械蹋,盡管她已經(jīng)帶打印版簡(jiǎn)歷...
    芳姐育兒閱讀 5,084評(píng)論 0 3
  • 父親出院以來(lái)出皇,基本上都是臥床休息。我仔細(xì)觀察他的神態(tài)哗戈,覺(jué)得他身體狀況還好郊艘。雖然手術(shù)過(guò)后身體還有些虛弱,但是...
    馮俊龍閱讀 507評(píng)論 1 5