react 好用的排序插件--列表支持


好用的拖拽插件

react-dnd(以前做自定义拖拽时常用的 自由度高 但复杂度也偏高)

react-sortable-hoc(只支持列表 若是列表使用 实为上上之选)

官方地址:https://github.com/clauderic/react-sortable-hoc

修改拖拽样式 添加helperClass样式 绑定在 const SortableList = SortableContainer(()=>{}) 上

You can provide a class you'd like to add to the sortable helper to add some styles to it

你可以提供一个你想添加到 sortable 助手的类来添加一些样式

helperClass="custom-row-dragging"

关键方法--通过新老索引实现拖拽

const onSortEnd = (oldIndex: number, newIndex: number) => {
    if (oldIndex !== newIndex) {
      // 逻辑处理
    }
  };

手写列表:

import React from 'react';
import { observer } from 'mobx-react';
import { SortableContainer, SortableElement } from 'react-sortable-hoc';
import { arrayMoveImmutable } from 'array-move';
import { Input, Button } from 'antd';
import AppIcon from '@/components/AppIcon';
import styles from '../../index.module.less';

const SortableItem = SortableElement(
  (props: { item: two_level_class; idx: number; setData: Function }) => {
    const { item, idx, setData } = props;
    const { id, name, sort, customId } = item;
    return (
      
{idx + 1} setData('subMenuModels', e.target.value, id || customId) } />
); }, ); const SortableList = SortableContainer( ({ items, setData }: { items: two_level_class_list; setData: Function }) => { return (
    {items.map((item, index) => ( ))}
); }, ); interface IProps { list: two_level_class_list; setList: Function; setData: Function; } const Index = ({ list, setList, setData }: IProps) => { const onSortEnd = ({ oldIndex, newIndex, }: { oldIndex: number; newIndex: number; }) => { setList((value: ClassItem) => { return { ...value, subMenuModels: arrayMoveImmutable(list, oldIndex, newIndex), }; }); }; return ( ); }; export default observer(Index);

  

table:

// 一级分类排序(table)
import React from 'react';
import { observer } from 'mobx-react';
import { Table, Button } from 'antd';
import {
  SortableContainer,
  SortableElement,
  SortableHandle,
} from 'react-sortable-hoc';
import AppIcon from '@/components/AppIcon';

const DragHandle = SortableHandle(() => );
const SortableItem = SortableElement((props: any) => );
const SortableBody = SortableContainer((props: any) => );
interface IProps {
  onDelete: Function;
  handleOpenEdit: Function;
  onClassDrag: Function;
  classlist: ClassList;
}
const Index = (props: IProps) => {
  const { handleOpenEdit, onDelete, classlist, onClassDrag } = props;

  const columns = [
    {
      title: '',
      dataIndex: 'index',
      width: 30,
      className: 'custom-drag-visible',
      render: () => ,
    },
    {
      title: '排序',
      dataIndex: 'sort',
    },
    {
      title: '一级分类',
      dataIndex: 'name',
    },
    {
      title: '二级分类',
      dataIndex: 'subMenuModels',
      render: (list: two_level_class_list) => list.map(m => m.name).join('、'),
    },
    {
      title: '操作',
      dataIndex: 'id',
      editable: true,
      fixed: 'right',
      render: (text: string, record: ClassItem) => {
        return (
          
); }, }, ]; const onSortEnd = (oldIndex: number, newIndex: number) => { if (oldIndex !== newIndex) { const sourceMenuId = classlist[oldIndex].id; const targetMenuId = classlist[newIndex].id; onClassDrag({ sourceMenuId, targetMenuId }); } }; const DraggableContainer = (props: any) => { return ( onSortEnd(oldIndex, newIndex)} {...props} /> ); }; const DraggableBodyRow = ({ ...restProps }) => { const index = classlist.findIndex( x => x.index === restProps['data-row-key'], ); return ; }; return ( DraggableContainer(props), row: (props: any) => DraggableBodyRow(props), }, }} /> ); }; export default observer(Index);

 

坑点:(不确定是不是sortable引起的)

1、弹框里面div点击事件无法触发,改用button

2、拖拽是脱离了文档流 又因为 弹框也是脱离了文档流 所以拖拽样式被弹框遮住了 可用z-index覆盖