React 拖拽排序

这篇文章基本骨架来自:文件点击上传和拖拽上传

今天我们要解决的问题就是页面上我们上传了多个文件,我们需要怎么实现移动拖拽排序的效果。

借用插件,先安装:

npm install --save react-sortable

参考官方文档:https://www.npmjs.com/package/react-sortable
实现效果:

React 拖拽排序_第1张图片
拖拽排序

思路:

  • 要求每个图片必须是一个单独的组件
    图片组件配置一共三步:
import React, { Component } from 'react'
// ①引包
import {sortable} from "react-sortable";
// ②装饰器语法进行组件装饰,注意这个装饰器就一个圆括号
// ③根 div 加上{...this.props}
@sortable
export default class Sortable extends Component {
    render() {
        return (
            
) } }

如果不使用@这个语法糖就得这样写:

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

class Sortable extends Component {
    render() {
        return (
            
) } } // ②装饰器语法进行组件装饰,注意这个装饰器就一个圆括号 export default sortable(Sortable)

到这里拖拽图片的话基本就可看见拖拽效果,但是还不能看到排序的效果。

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

第一个地方:给子组件一个 sortId 一般 key 用啥就给它啥
第二个地方:items 给它的值就是当前进行 map 的数组
第三个地方:一个函数,很明显是使用排序好的数组来更新当前数组

没啦配置完成。

以下是 2019年08月29日的补充

二、react 拖拽的进化

上面的拖拽是非常的简单,特别像我以前使用原生 JS 模仿后台写的一个九宫格拖拽。这种有一个缺点,没有动画,在重视用户体验的情况下,这种插件是万万不能用的。其实实现动画原理也特别的简单,再源码在加个动画延迟就行了。今天在看 react-sortable npm 官网的时候,发现它推荐了两个动画特别流畅的 npm 包。react-sortable-hocreact-beautiful-dnd 。随便选一个用一下,react-sortable-hoc的下载量高一点就用它了。开始:

  • 安装两个插件
npm install --save react-sortable-hoc
npm install --save array-move

先解释第二个:
array-move 就一个 API,它的主要作用就是用来交换数组中元素的位置。我们用 node 进行调试 1.js 文件,调试结果如下:

// 引包
const arrayMove = require('array-move');
// 创建一个数组
const input = ['a', 'b', 'c'];
 
// 以下三个排序实例
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 运行文件,控制台输出结果如下:

C:\Users\Administrator\Desktop\my>node 1.js
[ 'a', 'c', 'b' ]
[ 'c', 'a', 'b' ]
[ 'b', 'a', 'c' ]
  • 高阶函数
    在熟练使用 react-sortable-hoc 之前,先熟悉高阶函数。

高阶函数的定义简单来讲就是:高阶函数(Higher Order Function)=> 参数或返回值为函数

我们常见的有数组的遍历方式 Map、Reduce、Filter、Sort;常用的 redux 中的 connect 方法也是高阶函数。

这里在补充一个专有名词:函数的 柯里化

维基百科上:Currying(柯里化)是把接受多个参数的函数变换成接受一个单一参数(最初函数的第一个参数)的函数,并且返回接受余下的参数而且返回结果的新函数的技术。

说白了就是一个函数调用的时候形参至少多余一个,柯里化就是在保证函数功能不变的情况下,把函数调用的形参限定只能是一个。

看一个简单加法器的案例:

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

// 柯里化
function add(x){
    // x这里属于闭包的概念
    return function(y){
        return x + y;
    }
}
add(8)(9);

这玩意有啥用那,有函数不就行了?

可以提高函数的复用,例如一个字符串多次进行不同类型的正则查询。这个过程又有一个概念叫预处理

请看演示:

// 正常正则验证字符串 reg.test(txt)

// 函数封装后
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里面筛选只筛选出数字或字母!");
// 柯里化不像普通函数一样老是需要传入形参txt
has(/\d+/g); //true
has(/[a-z]/g)//true
  • react-sortable-hoc 使用
    react-sortable-hoc 提供了两个特别重要的 API ,分别是SortableContainer 和 SortableElement 看英文的意思也知道,SortableElement用来装饰每个要拖拽的组件,相对于SortableContainer 要装饰的组件,SortableElement 装饰的组件是子组件。

  • SortableElement 提供了一个 index 属性来进行子组件排序。

  • SortableContainer 提供一个方法 onSortEnd 。这个函数可以结构两个形参。{oldIndex, newIndex} 一个是拖拽元素的标记,一个是将要放的那个地方标记。最后在使用 arrayMove 交换数组的位置。axis 是拖拽的方向,默认是 y ,垂直拖拽,x 表示只可以水平拖拽。

搞清楚这些上案例:
文件夹的逻辑结构就是 App.js 请求数据,数据是个数组传给子组件 B (用SortableContainer装饰),孙子组件 A 来呈现图片(用SortableElement装饰),另外本案例使用了语法糖@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 (
            
) } }

子组件 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 (
            
{this.props.arr.map((item,index)=>)}
) } }

孙子组件A.js:

import React, { Component } from 'react';
import { sortableElement } from 'react-sortable-hoc';
@sortableElement
export default class A extends Component {
    constructor(){
        super();
    }
    render() {
        return (
            
{}
) } }

运行效果:


react-sortable-hoc

你可能感兴趣的:(React 拖拽排序)