本网站(662p.com)打包出售,且带程序代码数据,662p.com域名,程序内核采用TP框架开发,需要联系扣扣:2360248666 /wx:lianweikj
精品域名一口价出售:1y1m.com(350元) ,6b7b.com(400元) , 5k5j.com(380元) , yayj.com(1800元), jiongzhun.com(1000元) , niuzen.com(2800元) , zennei.com(5000元)
需要联系扣扣:2360248666 /wx:lianweikj
react 实现表格列表拖拽排序的示例
iamgeek · 128浏览 · 发布于2023-02-01 +关注

本文主要介绍了react 实现表格列表拖拽排序,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧

问题描述

在项目开发中,遇到这样一个需求:需要对表格里面的数据进行拖拽排序。

效果图如下所示:

在这里插入图片描述

思路

安装两个插件:

  • react-sortable-hoc (或者 react-beautiful-dnd)

  • array-move

npm install --save react-sortable-hoc
npm install --save array-move

解析

1. react-sortable-hoc

react-sortable-hoc 是一组 react 高阶组件(参数或返回值为函数),用于实现拖动排序功能,可以将任何列表转换为动画,可访问和触摸友好的可排序列表。可以和现有组件集成,支持拖动手柄、自动滚动、锁定轴和操作事件等功能,有着流程的动画效果。可水平、垂直拖动。

react-sortable-hoc 的使用:

react-sortable-hoc 提供了两个特别重要的API

  • SortableContainer :是所有可拖拽排序元素的容器

  • SortableElement :是每个要拖拽排序元素的容器

  • SortableHandle :是定义拖拽手柄的容器

import { SortableHandle } from 'react-sortable-hoc';
import { MenuOutlined } from '@ant-design/icons';
 const DragHandle = SortableHandle(() => <MenuOutlined style={{ cursor: 'grab', color: '#999' }
 } />)
  {
            title: '拖动排序',
            dataIndex: 'sort',
            width: 120,
            align: 'center',
            className: 'drag-visible',
            editable: false,
            render: () =>{
                if (editable) return <DragHandle />;
                return <span>禁止拖动</span>
            },
        },

SortableHandle 就是指下面的箭头部分

在这里插入图片描述

SortableElement 提供了一个 index 属性来进行对每个要拖拽元素的排序

SortableContainer 提供一个方法 onSortEnd,这个方法可以解构两个形参:{ oldIndex , newIndex },一个是拖拽元素的标记,一个是将要放的地方的标记。

最后在使用 arrayMoveImmutable 交换数组的位置。

axis 表示拖拽的方向,x 是水平拖拽,y 是垂直拖拽,默认是垂直拖拽

2. array-move

array-move 其实就是一个 API,它的主要作用是用来交换数组中元素的位置。

看下面的实例:

// 在tsx文件中
import React, { useEffect } from 'react';
import { arrayMoveImmutable } from 'array-move';
 const Index = () => {
    useEffect(() => {
        let arr = ['a', 'b', 'c']
        let result = arrayMoveImmutable(arr, 1 , 2)
        console.log(result)
        // 结果输入为: [ 'a', 'c', 'b' ]
    })
}
 export default Index

使用

import { SortableContainer, SortableElement, SortableHandle } from 'react-sortable-hoc';
import { arrayMoveImmutable } from 'array-move';
 // 定义拖拽的table 容器
const DragTableContainer = SortableContainer((props) => <tbody {...props}>)
 // 定义 拖拽的 行
const DragTableItem = SortableElement((props) => <tr {...props}>)
 // 定义拖拽手柄
const DragHandle = SortableHandle(() => (
    <MenuOutlined title='拖拽排序' />
))
 // 表格排序方法
const onSortEnd = ({oldIndex, newIndex}: {oldIndex: number; newIndex: number }) => {
        if (oldIndex !== newIndex) {
            const newData: any[] = arrayMoveImmutable(([] as any[]).concat(dataSource), oldIndex, newIndex).filter((el: any) => !!el);
            handleAllSave(newData) // 父组件传过来的方法,用于更新表格第一列的序号
        }
    }
 // 所有可拖拽排序元素的容器
// DragTableContainer 是上面通过 SortableContainer 定义的拖拽的table 容器
// useDragHandle  参数,意思是: 使用行把手拖拽行排序
// disableAutoscroll 参数,禁止自动滚动
// helperClass 参数,可修改拖拽样式
// onSortEnd   `SortableContainer` 提供的一个方法,这个方法可以解构两个形参:`{ oldIndex ,  
newIndex }`,一个是拖拽元素的标记,一个是将要放的地方的标记,用于表格拖拽排序
 const DraggableContainer = (props: any) => <DragTableContainer useDragHandle disableAutoscroll
  helperClass="row-dragging" onSortEnd={onSortEnd} {...props}/>
  // 定义 拖拽的 行
 // DraggableBodyRow  返回的是由 SortableItem  包裹的每一行元素
 const DraggableBodyRow = ({ className, style, ...restProps}: any) => {
    const index = dataSource.findIndex((x: any) => x.orderNum === restProps['data-row-key']);
    return (<SortableItem index={index} {...restProps} />)
}
  // ----------------------------------------------------------------------------------------
// ----------------------------------------------------------------------------------------
 // 封装的子组件
const EditableTable = (props: any) => {
    let { title = '', subtitle = '',  columns, rowClassName = () => 'editable-row', dataSource, 
    handleSave, handleAllSave,  rowKey, placeholder,  clickRow, loading = false, scroll } 
    = props;
    const styles = {
        tabletitle: { fontWeight: 800, color: '#0095ff', fontSize: '16px' },
        subtitle: { color: '#000000', fontSize: '12px' },
    };
     columns = columns.map((col: any) => {
        if (!col.editable) {
            return col;
        }
        return {
            ...col,
            onCell: (record: any) => ({
                record,
                isRowDisable: col.isRowDisable,
                isNumber: col.isNumber,
                editable: col.editable,
                editdisable: col.editdisable,
                dataIndex: col.dataIndex,
                title: col.title,
                handleSave: handleSave,
                formRules: col.rules,
                placeholder: col?.placeholder,
                precision: col?.precision,
                min: col?.min,
                step: col?.step,
                max: col?.max,
                formatter: col?.formatter,
                parser: col?.parser,
            }),
        };
    });
    /**
     * 表格行属性
     * @param record 表格每行的数据
     * @returns
     */
    const onRow = (record: any) => {
        return {
            onClick: clickRow ? () => clickRow(record) : undefined,
        }
    }
     const onSortEnd = ({oldIndex, newIndex}: {oldIndex: number; newIndex: number }) => {
        if (oldIndex !== newIndex) {
            const newData: any[] = arrayMoveImmutable(([] as any[]).concat(dataSource), 
            oldIndex, newIndex).filter((el: any) => !!el);
            handleAllSave(newData)
        }
    }
     const DraggableContainer = (props: any) => <SortableBody useDragHandle disableAutoscroll 
     helperClass="row-dragging" onSortEnd={onSortEnd} {...props}/>
     const DraggableBodyRow = ({ className, style, ...restProps}: any) => {
        const index = dataSource.findIndex((x: any) => x.orderNum === restProps['data-row-key']);
        return (<SortableItem index={index} {...restProps} />)
    }
     return (
        <Fragment>
            <div style={{ display: 'flex', marginBottom: '6px' }}>
                <Table
                    className="wrap"
                    style={{ width: '100%' }}
                    locale={{ emptyText: '暂无数据' }}
                    components={{
                        body: {
                            wrapper: DraggableContainer,
                            row: DraggableBodyRow,
                            // cell: EditableCell
                        }
                    }}
                    rowClassName={rowClassName}
                    bordered
                    dataSource={dataSource}
                    columns={columns}
                    pagination={false}
                    rowKey='orderNum'
                    scroll={scroll || { y: 500 }}
                    onRow={onRow}
                    loading={loading}
                />
            </div>
        </Fragment>
    );
};
 export default memo(EditableTable);


相关推荐

PHP实现部分字符隐藏

沙雕mars · 1312浏览 · 2019-04-28 09:47:56
Java中ArrayList和LinkedList区别

kenrry1992 · 896浏览 · 2019-05-08 21:14:54
Tomcat 下载及安装配置

manongba · 957浏览 · 2019-05-13 21:03:56
JAVA变量介绍

manongba · 953浏览 · 2019-05-13 21:05:52
什么是SpringBoot

iamitnan · 1077浏览 · 2019-05-14 22:20:36
加载中

0评论

评论
努力追求卓越,极致,这么一个GEEK人,希望可以跟大家认识,交流一下。
分类专栏
小鸟云服务器
扫码进入手机网页